一、Decorator 是什么
- 定义:Decorator 是一个只包含"单个子元素"的轻量级布局基类,用于在不改变子元素类型的前提下,为其增加额外外观或布局行为(如边框、内边距、缩放、装饰层等)。
- 特点:
- 仅一个子元素(Child)。
- 常用于控件模板或项模板中精简视觉树与成本。
- 常见派生类:Border、Viewbox、BulletDecorator、AdornerDecorator。
二、常见派生类与典型功能
- Border:为单个子元素提供背景、边框、圆角和 Padding。
- Viewbox:对单个子元素进行整体缩放(Uniform/Fill/UniformToFill)。
- BulletDecorator:在一行内排布"子弹元素(Bullet)+ 内容元素(Child)",常见于 CheckBox/RadioButton 模板。
- AdornerDecorator:在可视树中插入一个 AdornerLayer,便于在其子树上的元素之上绘制装饰(验证标记、拖拽手柄、选择框等)。
三、使用方式(Active Document)
- 在当前文件演示 Border/Viewbox/BulletDecorator/AdornerDecorator 的典型用法
xml
<UserControl x:Class="H.Test.DataGrid.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Margin="12" Orientation="Vertical" >
<!-- Border:单子元素 + 背景/边框/圆角/内边距 -->
<Border Background="#FFF7F9FC"
BorderBrush="#FF6AA0E8"
BorderThickness="1"
CornerRadius="6"
Padding="12">
<TextBlock Text="使用 Border 包裹单个内容(圆角 + 内边距 + 边框)" TextWrapping="Wrap"/>
</Border>
<!-- Viewbox:整体缩放子内容 -->
<Viewbox Stretch="Uniform" Height="80" Margin="0,8,0,0">
<Grid Width="160" Height="40" Background="#FFEFF3FA">
<TextBlock Text="会整体等比缩放" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Viewbox>
<!-- BulletDecorator:子弹(图标) + 文本 -->
<BulletDecorator Background="Transparent" Margin="0,8,0,0">
<BulletDecorator.Bullet>
<Ellipse Width="14" Height="14" Fill="#4090F0" Stroke="#2E6CB8"/>
</BulletDecorator.Bullet>
<TextBlock Text="图标 + 文本的轻量横排" Margin="8,0,0,0" VerticalAlignment="Center"/>
</BulletDecorator>
<!-- AdornerDecorator:为其子树提供 AdornerLayer -->
<AdornerDecorator Margin="0,8,0,0">
<Grid x:Name="AdornTarget" Width="220" Height="80" Background="#FFFDF7E7">
<TextBlock Text="运行时给我加一个红色装饰框" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</AdornerDecorator>
</StackPanel>
</UserControl>
csharp
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
namespace H.Test.DataGrid
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
// 在 Loaded 后给 AdornTarget 加一层简单的矩形 Adorner
Loaded += (_, __) =>
{
var layer = AdornerLayer.GetAdornerLayer(AdornTarget);
if (layer != null)
{
layer.Add(new SimpleRectAdorner(AdornTarget));
}
};
}
}
// 一个最小 Adorner:在目标元素边界上绘制红色虚线框
internal sealed class SimpleRectAdorner : Adorner
{
public SimpleRectAdorner(UIElement adornedElement) : base(adornedElement) { }
protected override void OnRender(DrawingContext dc)
{
var rect = new Rect(this.AdornedElement.RenderSize);
var pen = new Pen(Brushes.Red, 1) { DashStyle = DashStyles.Dash };
dc.DrawRectangle(null, pen, rect);
}
}
}
四、何时优先考虑 Decorator 派生类
- 只有一个子元素,且需要附加外观或行为:优先用 Border/Viewbox/BulletDecorator 等,避免为单子元素使用通用 Panel,能减小视觉树、降低测量/排列成本。
- 需要在元素上方绘制装饰层:用 AdornerDecorator 包起需要被装饰的区域。
五、文档链接
- Decorator | Microsoft Learn
- Border | Microsoft Learn
- Viewbox | Microsoft Learn
- BulletDecorator | Microsoft Learn
- AdornerDecorator | Microsoft Learn
了解更多
System.Windows.Controls 命名空间 | Microsoft Learn
控件库 - WPF .NET Framework | Microsoft Learn
使用 Visual Studio 创建新应用教程 - WPF .NET | Microsoft Learn
HeBianGu的个人空间-HeBianGu个人主页-哔哩哔哩视频