Adorner 装饰器
装饰器 Adorner
装饰器是WPF中较为常用的技术之一,也是不同于XAML的技术。
较为特殊。
特殊于装饰器全部由C#构成,不同于ControlTenmpate和Style的元素。
装饰器在某些方面能够简化前两者的代码量。
现在简单的说一下装饰器的入门用法(通常用法和附加属性一起使用)
Adorner是一个抽象类。
由于显示装饰器的方式有两种
直接装载现有WPF控件
绘制控件
直接装载现有控件:
这种方法需要重载四个Adorner方法
- GetVisualChild //获取Visual的子控件索引
- ArrangeOverride //确定装饰器的定位
- MeasureOverride //确定装饰器要约束道德大小
- VisualChildrenCount//获取VisualCollection的集合数量
重写之后就是
编写 私有的VsualCollection来存储你要装载的控件。
然后利用MeasureOverride和ArrangeOverride这两个方法来进行定位和约束大小。
下面的代码是 可以随时更新内容的装饰器
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Shapes; namespace 装饰器
{
public class TestAdorner : Adorner
{ private Grid _Grid;
private Ellipse _Ellipse;
private TextBlock _TextBlock;
private VisualCollection collection;
private UIElement _UIElement; public void UPDATE(string Text)
{
var grid = collection[] as Grid; (grid.Children[] as TextBlock).Text=Text; }
public TestAdorner(UIElement adornedElement) : base(adornedElement)
{
collection = new VisualCollection(this); _Grid = new Grid()
{
Width=
,
Height= };
_Ellipse = new Ellipse()
{
Fill = new SolidColorBrush(Colors.Red)
};
_TextBlock = new TextBlock()
{
HorizontalAlignment = HorizontalAlignment.Center
,
VerticalAlignment = VerticalAlignment.Center
,
FontSize= }; _Grid.Children.Add(_Ellipse); _Grid.Children.Add(_TextBlock); collection.Add(_Grid); _UIElement = adornedElement; } protected override int VisualChildrenCount => collection.Count; protected override Visual GetVisualChild(int index) => collection[index]; protected override Size MeasureOverride(Size constraint) => base.MeasureOverride(constraint); protected override Size ArrangeOverride(Size finalSize)
{
_Grid.Arrange(new Rect(finalSize));
_Grid.Margin = new Thickness((_UIElement as Button).ActualWidth-, , , (_UIElement as Button).ActualHeight-);
return base.ArrangeOverride(finalSize); }
}
}
XAML页面
<Grid>
<Button x:Name="TestBtn" Content="选中" Loaded="A_Loaded" Height="" Width=""/>
</Grid>
CS页面
namespace 装饰器
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
AdornerLayer layer; DispatcherTimer timer; public MainWindow()
{
InitializeComponent(); timer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds()
}; timer.Tick += Timer_Tick; } private void Timer_Tick(object sender, EventArgs e)
{
if (i == )
timer.Stop();
var b= layer.GetAdorners(TestBtn) ?? null;
if(b!=null)
{
var k=b[] as TestAdorner;
k.UPDATE(i.ToString()); }
else
{
var j = new TestAdorner(TestBtn);
j.UPDATE(.ToString());
layer.Add(j);
}
i++; } int i = ; private void A_Loaded(object sender, RoutedEventArgs e)
{
layer = AdornerLayer.GetAdornerLayer(TestBtn);
timer.Start();
}
}
}
效果图

绘制控件
绘制需要重载一个方法就好了
- OnRender//绘制控件
不过值得注意的是,绘制方式无法更新。至少我是不会。
现在给出代码
namespace 装饰器
{
public class TestAdornerOnRender : Adorner
{ public TestAdornerOnRender(UIElement adornedElement) : base(adornedElement) { } protected override void OnRender(DrawingContext drawingContext)
{ FormattedText t = new FormattedText(
"!!!!!",
CultureInfo.InstalledUICulture,
FlowDirection.LeftToRight,
new Typeface("微软雅黑"),
, new SolidColorBrush(Colors.Red)
);
drawingContext.DrawText(t, new Point(, ));
base.OnRender(drawingContext);
} }
}
xaml页面
<Grid>
<Button x:Name="TestBtn" Content="选中" Loaded="A_Loaded" Height="" Width=""> </Button>
</Grid>
cs 页面
private void A_Loaded(object sender, RoutedEventArgs e)
{
var layer = AdornerLayer.GetAdornerLayer(TestBtn); layer.Add(new TestAdornerOnRender(TestBtn)); }
截图

Adorner 装饰器的更多相关文章
- WPF和Expression Blend开发实例:Adorner(装饰器)应用实例
装饰器-- 表示用于修饰 UIElement 的 FrameworkElement 的抽象类 简单来说就是,在不改变一个UIElement结构的情况下,将一个Visual对象加到它上面. 应用举例: ...
- WPF装饰器
装饰器定义: 装饰器是一种特殊类型的 FrameworkElement,用于向用户提供可视化提示. 对于其他用户,装饰器可用于将功能控点添加到元素中或提供有关控件的状态信息. 装饰器可以在不改变原有的 ...
- Python高手之路【四】python函数装饰器
def outer(func): def inner(): print('hello') print('hello') print('hello') r = func() print('end') p ...
- python装饰器
今天看了装饰器的一些内容,感觉@修饰符还是挺抽象的. 装饰器就是在不用改变函数实现的情况下,附加的实现一些功能,比如打印日志信息等.需要主意的是装饰器本质是一个高阶函数,她可以返回一个函数. 装饰器需 ...
- Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化
本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解 ...
- [原创]django+ldap实现单点登录(装饰器和缓存)
前言 参考本系列之前的文章,我们已经搭建了ldap并且可以通过django来操作ldap了,剩下的就是下游系统的接入了,现在的应用场景,我是分了2个层次,第一层次是统一认证,保证各个系统通过ldap来 ...
- PHP 装饰器模式
装饰器模式:是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能. [装饰器模式中主要角色] 抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这 ...
- python cookbook 学习系列(一) python中的装饰器
简介 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓 ...
- python基础补漏-05-生成器和装饰器
[1]生成器 很难用简单的语言描述生成器. 生成器:从字面上来理解,就是以某种规则为基础,不断的生成数据的工具 生成器函数: 在函数中如果出现了yield关键字,那么该函数就不再是普通函数,而是生成器 ...
随机推荐
- Coursera连接不上(视频无法播放),修改hosts文件
视频问题 如果Coursera网站连接不上,或者视频加载不出来.可以通过如下方式进行配置: 一.找到hosts文件 Windows 系统, hosts文件位于: [C:\Windows\Syste ...
- failed to open stream: No such file or directory 报错解决方法
1.首先检查是否是文件名错误(比如有空格):是否因为路径不完整(比如缺少http://,或者缺少文件扩展名.doc等): 2.若是在本地中文名文件打开报错,我就是因为编码不一致导致: Windows中 ...
- java算法 第七届 蓝桥杯B组(题+答案) 10.压缩变换
10.压缩变换 (程序设计) 小明最近在研究压缩算法.他知道,压缩的时候如果能够使得数值很小,就能通过熵编码得到较高的压缩比.然而,要使数值很小是一个挑战. 最近,小明需要压缩一些正整数的序列,这些 ...
- Half Lambert
[Half Lambert] Half Lambert was a technique created by Valve as a way of getting the lighting to sho ...
- 3D Math Keynote
[3DMathKeynote] 1.常用公式. 1)(A*B)^T = B^T*A^T. 2)(A*B)^-1 = B^-1*A^-1. 3)|A*B| = |A|*|B|. 4)|M^T|=|M ...
- Python基础:字符串的常见操作
# 切片 # 切片 获取对象中一部分数据 [起始位置:结束位置(不包含):步长] qpstr = "山东张学友" result = qpstr[1: 3: 1] # 东张 prin ...
- 解剖Nginx·模块开发篇(1)跑起你的 Hello World 模块!
1 学习 Nginx 模块开发需要有哪些准备? 需要的预备知识不多,有如下几点: 有过一些 C 语言的编程经历: 知道 Nginx 是干嘛的,并有过编写或改写 Nginx 的配置文件的经历. OK,就 ...
- iOS判断字母、数字串
以下为NSString类的扩展方法,分别是判断字符串是否只是包含字母.是否只包含数字.是否只包含字母和数字: //字母 - (BOOL)cdm_isOnlyLetters { NSCharacterS ...
- Python Beautiful Soup 解析库的使用
Beautiful Soup 借助网页的结构和属性等特性来解析网页,这样就可以省去复杂的正则表达式的编写. Beautiful Soup是Python的一个HTML或XML的解析库. 1.解析器 解析 ...
- spring4-2-bean配置-2-属性注入细节
配置 bean,本章节中主要介绍蓝色文字部分. 配置形式:基于 XML 文件的方式:基于注解的方式 Bean 的配置方式:通过全类名(反射).通过工厂方法(静态工厂方法 & 实例工厂方法).F ...