随着WPF的推广,不得不重新拾起WPF来,因为这块的产品越来越多。
只能跟着MSDN来学了,所以想是在这里记录下学习的过程和对知识的理解。
先从最基本的吧,依赖项属性是WPF中不同的地方,先了解一下它吧。
“依赖项属性的用途在于提供一种方法来基于其他输入的值计算属性值”,这是官方的一句话,理解起来有点费劲。属性本身其实很简单,就是用来封装了字段的,本质上是两个访问器,来达到对字段值的读与写,以及从业务角度保护字段的业务有效性(因为大部分字段都有一定的业务含义,即有业务含义,就有一定范围,比如工资,是个小数的类型,但工资不可能是负数,所以在封装工资字段时,要在set访问器中作限制)。但依赖项属性不只这么简单了,属性的值不是简单的封装字段,而是根据其他的输入值来决定本属性的值。为什么要这样做?因为在WPF体系中,只有定义属性为依赖项属性,这个属性才支持样式设置,数据绑定,继承,动画和默认值。也就是这个属性才能具有WPF中的一些特点。
怎么样才能使一个属性成为依赖项属性呢?
首先,属性所在的类要直接或间接继承DependencyObject。这个类生成的对象表示一个具有依赖项属性的对象,这些对象,都能享用WPF的属性系统(属性系统主要是计算属性的值,并提供有关值已更改的系统通知)方面的服务。
这个类有两个比较重要的方法,GetValue(返回当前对象依赖项属性的当前有效值)和SetValue(设置依赖项属性的本地值)。
其实,属性对应的字段必需是公有,静态,只读的,类型为DependencyProperty。即public static readonly DependencyProperty 字段名,同时字段的命名也有规范,属性名+Property,字段在定义时,通过DependencyProperty.Register来实注册属性(只有注册了,才能使用WPF属性系统的服务)。
Register方法有三种重载,如下:
名称 | 说明 |
Register(String, Type, Type) | 使用指定的属性名称、属性类型和属性所在对象的类型。 |
Register(String, Type, Type, PropertyMetadata) | 使用指定的属性名称、属性类型、属性所在对象的类型和属性元数据注册依赖项属性。 |
Register(String, Type, Type, PropertyMetadata, ValidateValueCallback) | 使用指定的属性名称、属性类型、属性所在对象的类型、属性元数据和属性的值验证回调来注册依赖项属性。 |
在Register中,各个参数解释如下:
String:依赖属性的名字(不加Property,即字段的名字);
Type:属性的类型;
Type:属性所属对象的类型;
PropertyMetadata:依赖项对象的属性元数据,是一个PropertyMetadata类型,可能赋初始值。PropertyMetadata有一个object的构造函数;
ValidateValueCallback:表示用作回调的方法,这个类型是一个委托,用于验证依赖项属性的值的有效性,因为是委托,故它的构造参数为一个方法名。
最后,来构造依赖属性,与普通的属性有所区别:
Public 属性类型 属性名
{
Get
{
return (属性类型)this.GetValue(字段名);
}
Set
{
this.SetValue(字段名, value);
}
}
其中的GetValue和SetValue都是调用父类DependencyObject的方法。
完整的代码如下:
2 {
3 public static readonly DependencyProperty MyfieldProperty = DependencyProperty.Register( " Myfield " , typeof ( int ), typeof (MyClass), new PropertyMetadata( 0 ), new ValidateValueCallback( new MyClass().MyValidateMethod));
4 public int Myfield
5 {
6 get { return ( int )GetValue(MyfieldProperty); }
7 set { SetValue(MyfieldProperty, value); }
8 }
9 public bool MyValidateMethod( object value)
10 {
11 return true ; // 这里实现验证
12 }
13 }
14
WPF中,大部分对象的属性都是依赖项属性,用Button来举例,Button类的继承关系如下:
可以很明显的看到,Button是间接继承DependencyObject的。再看看他的属性:
拿ISDefault属性来看,它有一个IsDefalutProperty的字段,类型为DependencyProperty,IsDefault的代码如下:
完全与我们定义的依赖项属性一样。因为只有这样,这些属性才能使用WPF属性系统服务。