【笔记】在WPF中Decorator是什么以及何时优先考虑 Decorator 派生类
一、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 的典型用法
<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>
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 加一层简单的矩形 AdornerLoaded += (_, __) =>{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
WPF 介绍 | Microsoft Learn
使用 Visual Studio 创建新应用教程 - WPF .NET | Microsoft Learn
https://github.com/HeBianGu
HeBianGu的个人空间-HeBianGu个人主页-哔哩哔哩视频
GitHub - HeBianGu/WPF-Control: WPF轻量控件和皮肤库
GitHub - HeBianGu/WPF-ControlBase: Wpf封装的自定义控件资源库