原文:2000条你应知的WPF小姿势 基础篇<51-56 依赖属性>
前一阵子由于个人生活原因,具体见上一篇,耽搁了一阵子,在这里也十分感谢大家支持和鼓励。现在开始继续做WPF2000系列。
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师。最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,000 Things You Should Know About WPF 。他以类似微博式的150字简短语言来每天更新一条WPF和C#重要又容易被遗忘的知识。Follow他的博客也有一段日子了,很希望能够分享给大家。
本系列我不仅会翻译他的每一个tip,也会加入自己开发之中的看法和见解。本系列我希望自己也能和他一样坚持下来,每天的进步才能促成伟大。
在这里郑重说明.该系列是基于Sean Sexton先生的英文博客, Sean Sexton拥有全部版权和撤销权利。
前文:<1-7> , <8-14>,<15-21>22-27>, <28-33>,<34-39>,<40-44>,<45-50>
[小九的学堂,致力于以平凡的语言描述不平凡的技术。如要转载,请注明来源:小九的学堂。cnblogs.com/xfuture]
#51 依赖属性的实现
WPF客户端使用依赖属性的方式如同一般的CLR属性,但在类的定义中实现方式有差异。依赖属性增加了对数据绑定,属性集成和变更通知等等复杂的机制。 Class通过继承Denpendency Object来支持对Denpendency Properties的读写。
Class声明类型为DependencyProperty的新属性的静态变量。使用DependencyProperty.Register方法来创建静态实例。这个实例并不存储任何属性,只存储该属性的元数据。
public static readonly DependencyProperty AgeProperty = DependencyProperty.Register("Age", typeof(int), typeof(Person));
在继承了Denpendency Object的类中通过属性的 GetValue and SetValue方法来读写该依赖属性。
public int Age { get { return (int)GetValue(AgeProperty); } set { SetValue(AgeProperty, value); } }
#52 依赖属性的实现
标准的CLR属性值是存储在定义它的类的实例中。即使你从更改过它的默认值,它仍会占据这个对象相应的内存。
而依赖属性当且仅当它赋予非默认值时才会被存储。如若你未设置该属性的默认值,客户端读取时则会返回该属性的默认值。
依赖属性的值被拥有它并且继承了DependencyObject的类存储在一个数组中。这个储存了依赖属性值得数组,以及GetValue和SetValue方法来读写依赖属性值的特点,是继承自DependencyObject类的特点。这个内部的数组会存储每个设置过了非默认值的依赖属性值。
#53 注册依赖属性
实现依赖属性,首先要创建一个DependencyProperty的静态实例,因为其作用是为了读写元属性值,而并不是存储其实际属性值。所以其为静态的。
步骤:1. 声明一个静态的DependencyProperty实例:
public static readonly DependencyProperty AgeProperty;
2. 在静态的构造函数里,使用DependencyProperty.Register
static Person() { PropertyMetadata ageMetadata = new PropertyMetadata( 18, // Default value new PropertyChangedCallback(OnAgeChanged), new CoerceValueCallback(OnAgeCoerceValue)); // Register the property AgeProperty = DependencyProperty.Register( "Age", // Property's name typeof(int), // Property's type typeof(Person), // Defining class' type ageMetadata, // Defines default value & callbacks (optional) new ValidateValueCallback(OnAgeValidateValue)); // validation (optional) }
注册的前三个参数是必须的。
你也可以指定:1. 属性默认值。2.属性值改变时的通知方法。3. 验证值合法性。
#54 不要在DependencyProperty的Getter/Setter方法里加入逻辑
要实现依赖属性,需要使用 DependencyObject.GetValue and DependencyObject.SetValue 方法来实现Getter/Setter. 这样就实现了依赖属性正常的CLR属性功能。
public int Age { get { return (int)GetValue(AgeProperty); } set { SetValue(AgeProperty, value); } }
你不应该在get和set中使用除了getvalue和setvalue以外的方法。因为在xaml中获取或者赋值的时候,wpf会直接调用getvalue和setvalue方法,绕过你在里面写的逻辑。你应该在获取或者设置的回调方法里来写入你的逻辑。
#55 在Xaml或者cs代码里读取/写入依赖属性值
在Xaml或者cs代码里都可以读取/写入依赖属性的值。
例如在Person类里我们实现了三个依赖属性, FirstName, LastName, Age. 在Xaml中可以这样使用:
<m:Person x:Key="guy" FirstName="Samuel" LastName="Clemens" Age="75"/>
代码中可以这样:
Person author = (Person)this.Resources["guy"]; string info = string.Format("{0} {1}, aged {2}", author.FirstName, author.LastName, author.Age);
#56 清除依赖属性
在Xaml或者cs代码里都可以通过写入依赖属性的值来对默认或者继承的依赖属性值进行覆盖。
也可以使用DependencyObject.ClearValue方法来清除该依赖属性值。这将会取消掉任何设置在该依赖属性的值,恢复其为默认值。
Person p = new Person("Samuel", "Clemens"); Console.WriteLine(p.Age); // 18 (the default) // Setting a property value p.Age = 70; Console.WriteLine(p.Age); // 70 // Clear a property value p.ClearValue(Person.AgeProperty); Console.WriteLine(p.Age); // 18 again
下期会对依赖属性进行进一步的解析,希望大家可以继续支持~
PS. 昨晚下班后和同事一起做了WP的一个应用 疯狂猜词,本意是为了我们自己玩耍,后来就上线分享给大家,希望大家可以支持。初版本视觉略微贫瘠,缺少美工。之后我们会寻找美工神马的,也会继续迭代开发更新版本。
希望大家可以多多关注和建议,好评就更好啦~