如何使边框修剪子元素?

Bor*_*ris 16 wpf

我有一个BorderCornerRadius属性设置为10,这里面Border,有一个StackPanel.该面板包含两个Border分别带有蓝色和红色背景的s.

蓝色边框的左上角和右上角以及红色边框的左下角和右下角都伸出第一个边框的弯曲边缘.我希望将蓝色和红色边框修剪到父边框.那可能吗?

顺便说一下,我知道如果我为CornerRadius蓝色和红色边框的属性设置相同的值,它将遵循第一个的曲线.我不希望这样 - 我想要修剪.谢谢!

<Border 
    Width="200" 
    Height="200" 
    BorderThickness="1" 
    BorderBrush="Black"
    CornerRadius="10">
    <StackPanel>
        <Border Height="100" Background="Blue" />
        <Border Height="100" Background="Red" />
    </StackPanel>
</Border>
Run Code Online (Sandbox Code Playgroud)

Mar*_*nov 20

您可以为Clip属性编写转换器.例如,转换器应该实现IMultiValueConverter并绑定到实际大小和角半径.

public class BorderClipConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Length == 3 && values[0] is double && values[1] is double && values[2] is CornerRadius)
        {
            var width = (double)values[0];
            var height = (double)values[1];

            if (width < Double.Epsilon || height < Double.Epsilon)
            {
                return Geometry.Empty;
            }

            var radius = (CornerRadius)values[2];

            // Actually we need more complex geometry, when CornerRadius has different values.
            // But let me not to take this into account, and simplify example for a common value.
            var clip = new RectangleGeometry(new Rect(0, 0, width, height), radius.TopLeft, radius.TopLeft);
            clip.Freeze();

            return clip;
        }

        return DependencyProperty.UnsetValue;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

<Border CornerRadius="10">
    <Border.Clip>
        <MultiBinding Converter="{StaticResource BorderClipConverter}">
            <Binding Path="ActualWidth"
                        RelativeSource="{RelativeSource Self}"/>
            <Binding Path="ActualHeight"
                        RelativeSource="{RelativeSource Self}"/>
            <Binding Path="CornerRadius"
                        RelativeSource="{RelativeSource Self}"/>
        </MultiBinding>
    </Border.Clip>
</Border>
Run Code Online (Sandbox Code Playgroud)


pog*_*ama 7

通过使用该OpacityMask属性,还有一个仅限XAML的问题解决方案.诀窍是Grid在外边框内创建一个内部并将Grid的OpacityMask设置为另一个充当剪贴蒙版的元素.

<Border Width="200" Height="200"
        BorderThickness="1" BorderBrush="Black"
        CornerRadius="10">
    <Grid>
        <Grid.OpacityMask>
            <VisualBrush Visual="{Binding ElementName=clipMask}" Stretch="None" />
        </Grid.OpacityMask>
        <Border x:Name="clipMask" Background="White" CornerRadius="10" />
        <StackPanel Background="White">
            <Border Height="100" Background="Blue" />
            <Border Height="100" Background="Red" />
        </StackPanel>
    </Grid>
</Border>
Run Code Online (Sandbox Code Playgroud)

在上面的代码片段中,我使用了一个Border剪贴蒙版,但它也可以是另一个元素,只要它的填充颜色是不透明的.另请注意,clipMask Border也具有相同的功能CornerRadius.

灵感来自:http://www.codeproject.com/Articles/225076/Creating-Inner-Shadows-for-WPF-and-Silverlight