WPF装饰器

163 阅读1分钟

概述:装饰器(Adorner )可以用来增加一些装饰元素,如头像挂件、控件状态等
装饰器会绑定到其他UIElement上,并在 AdornerLayer 层中呈现出来(而不是被装饰的元素),通常使用2D坐标点进行定位。

说明
Adorner抽象类,具有装饰器实现的方法
AdornerLayer装饰器的表现层
AdornerDecorator装饰器与具体元素的关联集合

案例:使用装饰器在被装饰元素上显示四个圆

装饰单个元素

//自定义装饰器,要继承Adorner
public class SimpleCircleAdorner : Adorner
{
    public SimpleCircleAdorner(UIElement adornedElement)
      : base(adornedElement)
    {
    }

    // 实现装饰器渲染行为的常用方法是覆盖OnRender方法
    // 该方法作为渲染传递的一部分由布局系统调用
    protected override void OnRender(DrawingContext drawingContext)
    {
        Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);

        // 一些任意的绘图实现。
        SolidColorBrush renderBrush = new SolidColorBrush(Colors.Green);
        renderBrush.Opacity = 0.2;
        Pen renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5);
        double renderRadius = 5.0;

        //在每个角上画一个圆
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, renderRadius, renderRadius);
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, renderRadius, renderRadius);
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, renderRadius, renderRadius);
        drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, renderRadius, renderRadius);
    }
}
<Window
    x:Class="WpfApp12.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfApp12"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="184"
    Height="117"
    mc:Ignorable="d">
    <StackPanel Margin="10">
        <TextBox
            x:Name="txtBox"
            Width="50"
            Height="30" />
        <Button
            x:Name="btnOK"
            Margin="0,20,0,0"
            Click="BtnOK_Click"
            Content="增加装饰器" />
    </StackPanel>
</Window>
private void BtnOK_Click(object sender, RoutedEventArgs e)
{
    //调用静态方法 GetAdornerLayer 以获取要装饰的 UIElement 的 AdornerLayer 对象
    //GetAdornerLayer 从指定的 UIElement 开始向上遍历可视化树,并返回它找到的第一个装饰层。 
    //(如果未发现装饰器层,该方法将返回 null。)
    AdornerLayer myAdornerLayer = AdornerLayer.GetAdornerLayer(txtBox);
    myAdornerLayer?.Add(new SimpleCircleAdorner(txtBox));
}

在这里插入图片描述

在这里插入图片描述
装饰子集

AdornerLayer myAdornerLayer = AdornerLayer.GetAdornerLayer(txtBox);
foreach (UIElement item in panel.Children)
{
    myAdornerLayer.Add(new SimpleCircleAdorner(item));
}

在这里插入图片描述
在这里插入图片描述