wpfimagexamlimage-clipping

WPF image host with centering and clipping


I feel like I may need some converters, but this is what I want to do. I want a single Image control (since it is in a data template that is bound to real data) with the following parameters.

I have my XAML code below. This works as expected for pictures that are exactly 90x90 (i.e. they don't stretch, they center the image and the clipping works). For images > 90x90, the clipping works correctly but the image is not getting centered. For images < 90x90, the image gets centered but the clipping seems to place the image in the top-left area of the Image content so, the clipping clips the top-left portion of the image.

<Style x:Key="ImageStyle">
    <Setter Property="Width" Value="90" />
    <Setter Property="Height" Value="90" />
    <Setter Property="Stretch" Value="None" />
    <Setter Property="HorizontalAlignment" Value="Center" />
    <Setter Property="VerticalAlignment" Value="Center" />
    <Setter Property="Clip">
        <Setter.Value>
            <EllipseGeometry Center="45,45" RadiusX="40" RadiusY="40" />
        </Setter.Value>
    </Setter>
</Style>

<Grid>
    <!-- Other Stuff -->
    <Image Source="{Binding ImagePath}" Style="{StaticResource ImageStyle}" />
</Grid>

I can get rid of the second issue (small image clipping) by wrapping in a Grid and moving the clipping there, but large stuff doesn't center:

<Grid>
    <!-- Other Stuff -->
    <Grid Width="90" Height="90">
        <Grid.Clip>
            <EllipseGeometry Center="45,45" RadiusX="40" RadiusY="40" />
        </Grid.Clip>
        <Image Source="{Binding ImagePath}" Style="{StaticResource ImageStyle}" />
    </Grid>
</Grid>

Solution

  • I ended up having to just remove the Width and Height properties from the Image Style. Looking at it with WPF Snoop, the image is now bigger than the containing Grid but since the Grid has a fixed size, it centers itself on that.

    <Style x:Key="ImageStyle">
        <Setter Property="Stretch" Value="None" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
    
    <Grid>
        <!-- Other Stuff -->
        <Grid Width="90" Height="90">
            <Grid.Clip>
                <EllipseGeometry Center="45,45" RadiusX="40" RadiusY="40" />
            </Grid.Clip>
            <Image Source="{Binding ImagePath}" Style="{StaticResource ImageStyle}" />
        </Grid>
    </Grid>