装饰器定义:
装饰器是一种特殊类型的 FrameworkElement,用于向用户提供可视化提示。 对于其他用户,装饰器可用于将功能控点添加到元素中或提供有关控件的状态信息。
装饰器可以在不改变原有的控件结构的基础上将功能控点添加到元素中或在界面元素上提供视觉效果等。如WPF中的光标效果、焦点效果等就是通过装饰器实现的。如图 通过WPF inspector看到的装饰器层及Button的默认Focus效果:
![](https://i-blog.csdnimg.cn/blog_migrate/b5a2db1552059cd72b2b9cace2d2ba97.png)
![](https://i-blog.csdnimg.cn/blog_migrate/70680d545dd25de570161242536da45f.png)
装饰器是一个始终位于装饰元素或装饰元素集合上方的呈现图面,其呈现独立于该装饰器所绑定到的 UIElement 。WPF中的装饰器是在单独一个层AdornerLayer上进行绘制的,该层位于普通界面元素之上,而且允许存在多个AdornerLayer层进行叠加,当加入AdornerLayer层后,Adorner会默认使用其所装饰元素的左上角作为原点进行定位。
装饰器的应用:
1.向 UIElement 添加功能控点,使用这些控点,用户可以通过某种方式(调整大小、旋转、重新定位等等)操作元素。
2.提供可视反馈以指示各种状态,或响应各种事件。
3.在 UIElement 上叠加视觉效果。
4.从视觉上遮盖或重写 UIElement 的一部分或全部。
WPF 为装饰视觉元素提供一个基本框架。下表列出了装饰对象时使用的主要类型及其用途。
Adorner | 一个抽象基类,所有具体装饰器的实现都从该类继承。 |
AdornerLayer | 一个类,表示一个或多个装饰元素的装饰器的呈现层。 |
AdornerDecorator | 一个类,使装饰器层与元素集合相关联。 |
创建装饰器步骤:
1.自定义继承自Adorner的装饰器类:
public class FocusAdorner : Adorner { //被装饰的元素 FrameworkElement _adornedElement = null; //这里必须调用基类的构造函数 public FocusAdorner(UIElement adornedElement) : base(adornedElement) { } //通过复写onRender, 实现装饰器的呈现行为 protected override void OnRender(DrawingContext drawingContext) { } }
2.得到指定元素上方的可视化树中第一个装饰器层 public static AdornerLayer GetAdornerLayer(Visual visual)。
3.将装饰器添加到装饰器层:
private void WindowLoaded(object sender, RoutedEventArgs e) { AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(_label); adornerLayer.Add(new ScaleAdorner(_label)); }
小例子:为TextBox重新设计一个Focus效果:
public class FocusAdorner : Adorner { public FocusAdorner(UIElement adornedElement) : base(adornedElement) { this.IsHitTestVisible = false; } protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); Rect adornedElementRect = new Rect(this.AdornedElement.RenderSize); Pen renderPen = new Pen(new SolidColorBrush(Colors.Red), 1.0); drawingContext.DrawRectangle(new SolidColorBrush(Colors.Transparent), renderPen,adornedElementRect); } }
MainPage:
private void WindowLoaded(object sender, RoutedEventArgs e) { AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(texBox1); adornerLayer.Add(new ScaleAdorner(texBox1)); }
当TextBox获得焦点时效果: