【笔记】在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 的典型用法
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 包起需要被装饰的区域。

五、文档链接

了解更多

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封装的自定义控件资源库

相关推荐
wan5555cn3 小时前
AI视频生成技术:从想象到现实的视觉革命
人工智能·笔记·深度学习·算法·音视频
哈基鑫13 小时前
深度学习之图像分类笔记
笔记·深度学习·分类
润 下13 小时前
C语言——深入理解函数声明定义和调用访问
c语言·开发语言·经验分享·笔记·程序人生·其他
时光追逐者16 小时前
一款专门为 WPF 打造的开源 Office 风格用户界面控件库
ui·开源·c#·.net·wpf
He BianGu16 小时前
【笔记】介绍 WPF XAML 中 Binding 的 StringFormat详细功能
笔记·wpf
Rousson16 小时前
硬件学习笔记--78 MCU复位电路简介
笔记·学习
~无忧花开~17 小时前
JavaScript学习笔记(十七):ES6生成器函数详解
开发语言·前端·javascript·笔记·学习·es6·js
optimistic_chen18 小时前
【Java EE进阶 --- SpringBoot】Mybatis操作数据库(基础)
数据库·经验分享·spring boot·笔记·spring·java-ee·mybatis
ASKED_201919 小时前
ChatGPT From Zero To Hero - LLM学习笔记(一)
笔记·学习·chatgpt