Genusatplay
Genusatplay

Reputation: 771

Crop content of rounded-corner border with image out of border

I need to move and rotate the image outside of the rounded border

example: enter image description here

In How to make the contents of a round-cornered border be also round-cornered? find answer:

<Grid>
    <Grid.OpacityMask>
        <VisualBrush Visual="{Binding ElementName=Border1}" />
    </Grid.OpacityMask>
    <Border x:Name="Border1" CornerRadius="30" Background="Green" />
    <TextBlock Text="asdas das d asd a sd a sda" />
</Grid>

This works if the elements do not go out of bounds.

If using rotate and/or margin like this:

<Grid>
    <Grid.OpacityMask>
        <VisualBrush Visual="{Binding ElementName=_border1}" />
    </Grid.OpacityMask>
    <Border x:Name="_border1"
            BorderThickness="0"
            CornerRadius="30"
            Background="Green" />
    <TextBlock Text="SomeText"
               Foreground="Yellow" />
    <Image Source="https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_gmail_lockup_default_1x_r2.png"
           Margin="-5 0 0 0"
           Height="20"
           Width="55"
           Stretch="UniformToFill"
           VerticalAlignment="Top"
           HorizontalAlignment="Left"
           RenderTransformOrigin="0.5 0.5">
        <Image.RenderTransform>
            <RotateTransform Angle="-7" />
        </Image.RenderTransform>
    </Image>
</Grid>

The rounding is displaced

enter image description here

How can I crop the image like in the first example? Thanks for your help.

Upvotes: 1

Views: 560

Answers (2)

Paviel Kraskoŭski
Paviel Kraskoŭski

Reputation: 1419

I managed to achieve the desired result using Clip instead of OpacityMask. Then all the elements that need to be cropped must be children of the Border. If your Border needs to be dynamic, you need to bind the dimensions of the RectangleGeometry to the dimensions of the Border using Converter.

<Grid>
    <Border BorderThickness="0"
            CornerRadius="30"
            Background="Green">
        <Border.Clip>
            <RectangleGeometry RadiusX="30" RadiusY="30" Rect="0,0,500,400"/>
        </Border.Clip>
        <Grid>
            <TextBlock Text="SomeText"
                       Foreground="Yellow"/>
            <Image Source="https://ssl.gstatic.com/ui/v1/icons/mail/rfr/logo_gmail_lockup_default_1x_r2.png"
                   Margin="-5 0 0 0"
                   Height="20"
                   Width="55"
                   Stretch="UniformToFill"
                   VerticalAlignment="Top"
                   HorizontalAlignment="Left"
                   RenderTransformOrigin="0.5 0.5">
                <Image.RenderTransform>
                    <RotateTransform Angle="-7"/>
                </Image.RenderTransform>
            </Image>
        </Grid>
    </Border>
</Grid>

Clipping works!

Clipping works!

Upvotes: 1

Clemens
Clemens

Reputation: 128062

Something is going wrong with the viewport calculation of the VisualBrush. Not sure if that is a bug in WPF.

A workaround could be setting the viewport in absolute units, with Rectangle instead of a Border:

<Grid.OpacityMask>
    <VisualBrush
        Visual="{Binding ElementName=rect}"
        ViewportUnits="Absolute"
        Viewport="{Binding ElementName=rect, Path=RenderedGeometry.Rect}"/>
</Grid.OpacityMask>
<Rectangle x:Name="rect" RadiusX="30" RadiusY="30" Fill="Green"/>

Or simpler, with setting the Clip property instead of OpacityMask, but still supporting resize:

<Grid Clip="{Binding ElementName=rect, Path=RenderedGeometry}">
    <Rectangle RadiusX="30" RadiusY="30" Fill="Green" x:Name="rect"/>
    ...
</Grid>

Upvotes: 2

Related Questions