views:

138

answers:

2

I've run into a problem with WPF when I try to use DataBinding with an image as a background to a border. I have no problem rendering the image this way:

<Image Name="imgPlayer" Width="100" Height="100"
    Source="{Binding Converter={StaticResource ImageConverter}, Path=Image}"
/>

My DefaultImageConverter just checks if the image is null, and if so, returns a "we have no image" BitmapImage that is an embedded resource in the project. This also works great.

I'm not sure if it's critical but the image is actually coming from a MS SQL Server CE Image field, and the corresponding Entity field is actually a byte array. However, it works just fine.

Then, I decided to try to put a simple rounded border around the image to make it look better. My first attempt was to use a canvas with a border and the image but the square image paints over the rounded parts of the border. After doing some looking, I found you could actually paint an image as the background of the border. This is what I came up with:

<Border Height="100" Width="100" BorderBrush="Gray" CornerRadius="10" BorderThickness="5">
    <Border.Background>
        <ImageBrush>
            <ImageBrush.ImageSource>
                <BitmapImage StreamSource="{Binding Converter={StaticResource ImageConverter}, Path=Image}"/>
            </ImageBrush.ImageSource>
        </ImageBrush>
    </Border.Background>
</Border>

My problem is that I am getting an XML parsing error telling me that I have to either set UriSource OR StreamSource. I am setting StreamSource. I have also tried setting UriSource (having found a similar but opposite problem where the same problem was being encountered but using UriSource) and I get the same problem.

It will run, but just fails when it tries to reference this image.

Really I just want to put a rounded border around an image without the image painting over the corners. If there is a totally different way to do this, that works as well.

Hopefully this makes sense!

Regards, Mike

A: 

What you could do is create an Image and a Border in the same location, so that the Border overlays the Image. I.E.

        <Grid>
            <Image Name="imgPlayer" Width="100" Height="100" Source="{Binding Converter={StaticResource ImageConverter}, Path=Image}" />
            <Border Width="100" Height="100" BorderBrush="Gray" CornerRadius="10" BorderThickness="5" Background="Transparent" />
        </Grid>
This would still likely have the image showing in the rounded corners. The border doesn't draw over the corner's blank space.
Will Eddins
A: 

I was stumped by this for quite a while, and being new to XAML, finding solutions takes a little longer than if I was looking for a solution in C++ where I am a lot more comfortable.

However, as would have to be the case I was able to find a solution literally five minutes after posting my question, and here it is.

<Grid Grid.RowSpan="5">
    <!-- Rounded mask -->
    <Border Name="Mask" Background="White" CornerRadius="7"/>

    <StackPanel Width="100" Height="100" HorizontalAlignment="Center" VerticalAlignment="Top">
        <StackPanel.OpacityMask>
            <VisualBrush Visual="{Binding ElementName=Mask}"/>                        
        </StackPanel.OpacityMask>

        <Image Name="imgPlayer"                           
               Source="{Binding Converter={StaticResource ImageConverter}, Path=Image}" 
               MouseLeftButtonDown="Image_MouseRightButtonDown"
               />
    </StackPanel>
</Grid>

This code just handles rounding the corners of the image, or anything inside the stackpanel. I am going to look into this OpacityMask for more details, but it seems to do the trick. I can put one or more borders around it if I want. Very cool.

Regards, Mike

mkgrunder