您可以在其 ControlTemplate 中为 UserControl 的轮廓添加一个 Path 元素。 Path 的Fill、Stroke 和StrokeThickness 属性绑定到UserControl 的Background、BorderBrush 和(新定义的)OutlineThickness,因此您可以照常设置。
<UserControl x:Class="YourNamespace.Tile" ...>
<UserControl.Template>
<ControlTemplate TargetType="local:Tile">
<Grid>
<Path Fill="{TemplateBinding Background}"
Stroke="{TemplateBinding BorderBrush}"
StrokeLineJoin="Round"
StrokeThickness="{TemplateBinding OutlineThickness}"
Data="{TemplateBinding Outline}"/>
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</ControlTemplate>
</UserControl.Template>
<Grid>
...
</Grid>
</UserControl>
Path 绑定到 Tile 控件的两个依赖属性:
public partial class Tile : UserControl
{
public Tile()
{
InitializeComponent();
}
public static readonly DependencyProperty OutlineProperty =
DependencyProperty.Register(
nameof(Outline), typeof(Geometry), typeof(Tile));
public Geometry Outline
{
get { return (Geometry)GetValue(OutlineProperty); }
set { SetValue(OutlineProperty, value); }
}
public static readonly DependencyProperty OutlineThicknessProperty =
DependencyProperty.Register(
nameof(OutlineThickness), typeof(double), typeof(Tile),
new PropertyMetadata(1.0, (o, e) => ((Tile)o).UpdateOutline()));
public double OutlineThickness
{
get { return (double)GetValue(OutlineThicknessProperty); }
set { SetValue(OutlineThicknessProperty, value); }
}
protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);
UpdateOutline();
}
private void UpdateOutline()
{
var geometry = new StreamGeometry();
var size = RenderSize;
var border = OutlineThickness / 2d;
using (var sgc = geometry.Open())
{
sgc.BeginFigure(new Point(border, border), true, true);
sgc.LineTo(new Point(size.Width - 20, border), true, true);
sgc.LineTo(new Point(size.Width - border, 20), true, true);
sgc.LineTo(new Point(size.Width - border, size.Height - border), true, true);
sgc.LineTo(new Point(0, size.Height - border), true, true);
}
Outline = geometry;
}
}
现在根据需要扩展UpdateOutline 方法。
如果 XAML 设计者抱怨 ControlTemplate 的 TargetType,你也可以使用这个:
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<Grid>
<Path Fill="{TemplateBinding Background}"
Stroke="{TemplateBinding BorderBrush}"
StrokeLineJoin="Round"
StrokeThickness="{Binding OutlineThickness, RelativeSource={RelativeSource TemplatedParent}}"
Data="{Binding Outline, RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</ControlTemplate>
</UserControl.Template>