我有一个带有圆角的边框元素,包含一个3x3网格.网格的角落伸出边界.我该如何解决这个问题?我尝试使用ClipToBounds但没有得到任何结果.谢谢你的帮助
Mic*_*cah 57
这是一个继承自Border并实现适当功能的类的实现:
/// <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;
}
Run Code Online (Sandbox Code Playgroud)
And*_*lov 42
纯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>
Run Code Online (Sandbox Code Playgroud)
更新: 找到一种更好的方法来实现相同的结果.您现在也可以用任何其他元素替换Border.
<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>
Run Code Online (Sandbox Code Playgroud)
正如弥迦所说,ClipToBounds
不会合作Border.ConerRadius
.
有UIElement.Clip属性,它Border
继承.
如果您知道边框的确切大小,那么这是解决方案:
<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>
Run Code Online (Sandbox Code Playgroud)
如果尺寸是未知的或动态然后Converter
为Border.Clip
可以使用.请参见该解决方案在这里.
所以我刚刚遇到了这个解决方案,然后进入了Jobi提供的msdn论坛链接,花了20分钟编写我自己的ClippingBorder控件.
然后我意识到CornerRadius属性类型不是double,而是System.Windows.CornerRaduis,它接受4个双精度数,每个角落一个.
所以我现在要列出另一种替代解决方案,这很可能满足大多数人将来偶然发现这个帖子的要求......
假设您有XAML,如下所示:
<Border CornerRadius="10">
<Grid>
... your UI ...
</Grid>
</Border>
Run Code Online (Sandbox Code Playgroud)
问题是Grid元素的背景渗透并显示过去的圆角.确保您<Grid>
具有透明背景,而不是将相同的画笔分配给<Border>
元素的"背景"属性.不再流失角落,也不需要一大堆CustomControl代码.
确实,从理论上讲,客户区仍然有可能超越角落的边缘,但是您可以控制该内容,因此您作为开发人员应该能够有足够的填充,或者确保控件的形状在旁边边缘是合适的(在我的情况下,我的按钮是圆的,所以非常适合在角落没有任何问题).
小智 5
使用 @Andrew Mikhailov 的解决方案,您可以定义一个简单的类,这使得VisualBrush
无需手动为每个受影响的元素定义 a :
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);
}
}
Run Code Online (Sandbox Code Playgroud)
要测试这一点,只需编译以下两个示例:
<!-- 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>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
23174 次 |
最近记录: |