#使用技巧#WPF Adorner 装饰器实现“加载中“

业务背景

开发过程中,我们希望在控件上添加(数字/状态)徽标,以及在列表数据加载时添加一层"加载中"蒙版。

以前的做法,实现徽标,可能会选择重写控件模板;实现蒙版,可能会全局(整个界面)增加一层蒙版。这些做法一是会改变原有的空间结构,二是影响范围过广,不能精准按需控制操作。

现在可以使用装饰器来实现上述或类似的功能。装饰器,顾名思义,就是在不改变原有空间结构的条件下,为控件增加了一些新的功能,或是为控件外观添砖加瓦。

下面将展示"加载中"蒙版的具体实现:

实现步骤

1、创建"LoadingAdorner.cs"加载中装饰器,继承 Adorner,添加依赖属性:IsLoding 是否加载中、Text 加载中显示文本、TemplateStyleKey 加载中显示样式标识;

构造函数中,给装饰器的集合添加一个 Control 控件,控件绑定样式,通过 IsLoading 控制控件是否显示、Text 表示控件的呈现文案、TemplateStyleKey 对应资源文件下的样式。主要代码如下:
添加 Visual 视图:
在这里插入图片描述
在这里插入图片描述
添加视图后,需要设置 Control 的大小,先了解一下 几个概念:Measure 和 Arrange,两者都是 UIElement 的方法;MeasureOverride 和 ArrangeOverride,这两个方法是 FrameworkElement 的方法,FrameworkElement 是 UIElement 的子类。

Measure 方法自顶而下,递归调用各子控件的 Measure 方法,Measure 方法会把该控件所需的大小控件存在 desired size 属性中,控件根据各子控件的 desired size 属性确定自身空间大小,并返回自己的 desired size;

Arrange 方法发生在 Measure 中,传入 Measure 方法计算到的大小,利用控件的位置设置分配子控件的位置。

MeasureOverride 用于计算本身及其子控件的大小,传入父容器分配的可用空间,返回该容器根据其子元素大小计算确定的在布局过程中所需的大小;

ArrangeOverride 用于布局本身及其子控件的位置和大小,传入父容易最终分配的控件大小,返回使用的实际大小。

在这里插入图片描述
通过 TemplateStyleKey 属性值变化时,更新 Control 的样式:
在这里插入图片描述
2、创建"LoadingStyle.xaml"加载中静态资源,样式标识为 LoadingTest;
在这里插入图片描述
3、创建"LoadingAttachProperty.cs"加载中附加属性:IsLoding 是否加载中、Text 加载中显示文本、TemplateStyleKey 加载中显示样式标识;
在这里插入图片描述
在这里插入图片描述
4、前端界面引入,并不是所有控件都有 AdornerDecoretor 容器,如 TextBlock、UserControl,就没有这个容器层,故可以在界面最外层加上 ,然后给对应的控件加上依赖属性即可 ctrl:LoadingAssists.IsLoading=“True”;

在这里插入图片描述

效果

在这里插入图片描述

注释

Decorator 和 Adorner,它们都有“装饰品”的意思。
Decorator 类
负责包装某个 UI 元素,以提供额外的行为。它有一个类型为 UIElement 的 Child 属性,其中含有待包装的内容。Decorator 可被用于添加简单的视觉装饰,例如边界(Border),或者更复杂的行为,例如 ViewBox,AdornerDecorator,或是 InkPresenter。
当你从 Decorator 派生新类时,可以暴露一些有用的依赖属性来定制它。例如,Border 类暴露它的 BorderBrush,BorderThickness,和 CornerRadius,它们都会影响包围 child content 的边界的绘制方式。
Adorner 类
既然已经有了 Decorator,为什么还需要 Adorner 类?因为它们的功能不同。
Decorator 类用于在 child content 的外周绘制装饰;Adorner 允许你在已经存在的 visual 元素之上叠加 visuals 。
简单的想法是,它们是另一组交互的 visual,提供与主 visual 交互的额外途径。这看起来比较复杂,但是想想出现在典型图表软件元素中的窗口小部件(widgets),例如调整尺寸的把柄(resizing grips)。那些就是叠加在元素之上的另一个 visual,它们装饰并提供额外的功能及交互。通过点击或拖动这些调节尺寸的把柄,用户可以改变其中控件的大小。
Adorner 类和 AdornerDecorator 一起工作,后者是一个不可见的平面,用于承载 adorners。为了成为可视树的一部分,adorners 必须有一个容器。AdornerDecorator 就是这个容器。
AdornerDecorator 通常被定义在可视树的顶端(如 Window Control 的 ControlTemplate)。这使得所有的 adorners 都位于窗口内容之上。

  • 34
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AdornerWPF一种特殊的视觉元素,可以用于在其他元素上添加装饰或者附加功能。Adorner通常用于实现在用户界面上的一些特殊效果,比如鼠标悬停提示、错误提示、操作提示等。 Adorner需要继承自Adorner类,并在构造函数调用基类的构造函数,并将需要装饰的元素作为参数传递进去。Adorner有一个AdornedElement属性,用于获取被装饰的元素。 Adorner有一个OnRender方法,用于绘制Adorner的外观。在OnRender方法可以使用DrawingContext来绘制Adorner的外观,也可以使用VisualBrush来填充Adorner的内容。 Adorner使用方法: 1. 创建一个Adorner类,继承自Adorner类,并在构造函数调用基类的构造函数,并将需要装饰的元素作为参数传递进去。 2. 重写Adorner类的OnRender方法,用于绘制Adorner的外观。 3. 在需要装饰的元素上调用AdornerLayer.GetAdornerLayer方法获取AdornerLayer对象。 4. 调用AdornerLayer的Add方法,将Adorner添加到AdornerLayer。 下面是一个简单的例子: ```csharp public class MyAdorner : Adorner { public MyAdorner(UIElement adornedElement) : base(adornedElement) { } protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); // 绘制Adorner的外观 drawingContext.DrawEllipse(Brushes.Red, null, new Point(AdornedElement.RenderSize.Width / 2, AdornedElement.RenderSize.Height / 2), AdornedElement.RenderSize.Width / 2, AdornedElement.RenderSize.Height / 2); } } // 在需要装饰的元素上添加Adorner var adornedElement = new Button { Content = "Click me!" }; var adornerLayer = AdornerLayer.GetAdornerLayer(adornedElement); var myAdorner = new MyAdorner(adornedElement); adornerLayer.Add(myAdorner); ``` 这个例子,我们创建了一个MyAdorner类,继承自Adorner类,并重写了OnRender方法,在OnRender方法绘制了一个红色的圆形。然后我们创建了一个Button元素,并将其作为参数传递给MyAdorner的构造函数,创建了一个AdornerLayer对象,并调用Add方法将MyAdorner添加到AdornerLayer,从而实现了在Button元素上添加了一个红色的圆形装饰器

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值