如何使圆angular边界的内容也是圆angular的?

我有一个包含3×3网格的圆angular边框元素。 网格的angular落突出了边界。 我该如何解决这个问题? 我尝试使用ClipToBounds,但没有得到任何地方。 谢谢你的帮助

这里是Jobi提到的这个线程的亮点

  • 装饰者(即边框)或布局面板(即Stackpanel)都不具备这种行为。
  • ClipToBounds用于布局。 ClipToBounds不会阻止一个元素超出其边界; 它只是防止儿童的布局“溢出”。 另外ClipToBounds = True对于大多数元素是不需要的,因为它们的实现不允许他们的内容的布局溢出。 最显着的例外是帆布。
  • 最后,Border将圆angular视为其布局边界内的graphics。

这里是一个inheritance自Border的类的实现,并实现了正确的function:

/// <Remarks> /// As a side effect ClippingBorder will surpress any databinding or animation of /// its childs UIElement.Clip property until the child is removed from ClippingBorder /// </Remarks> public class ClippingBorder : Border { protected override void OnRender(DrawingContext dc) { OnApplyChildClip(); base.OnRender(dc); } public override UIElement Child { get { return base.Child; } set { if (this.Child != value) { if(this.Child != null) { // Restore original clipping this.Child.SetValue(UIElement.ClipProperty, _oldClip); } if(value != null) { _oldClip = value.ReadLocalValue(UIElement.ClipProperty); } else { // If we dont set it to null we could leak a Geometry object _oldClip = null; } base.Child = value; } } } protected virtual void OnApplyChildClip() { UIElement child = this.Child; if(child != null) { _clipRect.RadiusX = _clipRect.RadiusY = Math.Max(0.0, this.CornerRadius.TopLeft - (this.BorderThickness.Left * 0.5)); _clipRect.Rect = new Rect(Child.RenderSize); child.Clip = _clipRect; } } private RectangleGeometry _clipRect = new RectangleGeometry(); private object _oldClip; } 

纯XAML:

 <Border CornerRadius="30" Background="Green"> <Border.OpacityMask> <VisualBrush> <VisualBrush.Visual> <Border Background="Black" SnapsToDevicePixels="True" CornerRadius="{Binding CornerRadius, RelativeSource={RelativeSource AncestorType=Border}}" Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Border}}" Height="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType=Border}}" /> </VisualBrush.Visual> </VisualBrush> </Border.OpacityMask> <TextBlock Text="asdas das d asd a sd a sda" /> </Border> 

更新:find一个更好的方法来实现相同的结果。 您现在也可以用任何其他元素replace边界

 <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> 

例

所以我只是遇到了这个解决scheme,然后跟随Jobi提供的msdn论坛链接,花了20分钟写我自己的ClippingBorder控制。

然后我意识到CornerRadius属性types不是双重的,而是System.Windows.CornerRaduis,它接受4个双打,每个angular落一个。

所以我现在要列出另一种替代解决scheme,这将最有可能满足将来偶然遇到这个post的大多数人的要求…

假设你有这样的XAML:

 <Border CornerRadius="10"> <Grid> ... your UI ... </Grid> </Border> 

问题是Grid元素的背景会stream过并显示圆angular。 确保您的<Grid>具有透明背景,而不是将相同的画笔分配给<Border>元素的“Background”属性。 没有更多的出血越过angular落,并不需要一大堆的CustomControl代码。

诚然,从理论上讲,客户区域仍然有可能超越angular落的边缘,但是您控制了内容,所以开发者应该能够拥有足够的填充,或者确保控件旁边的控件的形状边缘是合适的(在我的情况下,我的button是圆的,所以非常适合在angular落没有任何问题)。

正如Micah所提到的, ClipToBounds不能用于Border.ConerRadius

有UIElement.Clip属性,这是Borderinheritance关系。

如果你知道边界的确切大小,那么这里是解决scheme:

 <Border Background="Blue" CornerRadius="3" Height="100" Width="100"> <Border.Clip> <RectangleGeometry RadiusX="3" RadiusY="3" Rect="0,0,100,100"/> </Border.Clip> <Grid Background="Green"/> </Border> 

如果大小未知或dynamic,则可以使用Converter for Border.Clip 。 在这里看到解决scheme。

使用@安德鲁·米哈伊洛夫的解决scheme,你可以定义一个简单的类,这使得为每个受影响的元素定义一个VisualBrush手动是不必要的:

 public class ClippedBorder : Border { public ClippedBorder() : base() { var e = new Border() { Background = Brushes.Black, SnapsToDevicePixels = true, }; e.SetBinding(Border.CornerRadiusProperty, new Binding() { Mode = BindingMode.OneWay, Path = new PropertyPath("CornerRadius"), Source = this }); e.SetBinding(Border.HeightProperty, new Binding() { Mode = BindingMode.OneWay, Path = new PropertyPath("ActualHeight"), Source = this }); e.SetBinding(Border.WidthProperty, new Binding() { Mode = BindingMode.OneWay, Path = new PropertyPath("ActualWidth"), Source = this }); OpacityMask = new VisualBrush(e); } } 

要testing这个,只需编译以下两个示例:

 <!-- You should see a blue rectangle with rounded corners/no red! --> <Controls:ClippedBorder Background="Red" CornerRadius="10" Height="425" HorizontalAlignment="Center" VerticalAlignment="Center" Width="425"> <Border Background="Blue"> </Border> </Controls:ClippedBorder> <!-- You should see a blue rectangle with NO rounded corners/still no red! --> <Border Background="Red" CornerRadius="10" Height="425" HorizontalAlignment="Center" VerticalAlignment="Center" Width="425"> <Border Background="Blue"> </Border> </Border> 

使网格更小或边框更大。 以便边界元素完全包含网格。

或者看看你是否可以使网格的背景透明,以便“伸出”不明显。

更新:糟糕,没有注意到这是一个WPF的问题。 我不熟悉这一点。 这是一般的HTML / CSSbuild议。 也许它有帮助…