依赖项属性
依赖项属性专门针对WPF创建,当希望本不支持数据绑定、动画或其他WPF功能的部分代码添加这些功能时,也许创建依赖项属性。
只能为依赖对象(继承自DependencyObject的类)添加依赖项属性,幸运的是,WPF基础结构的关键部分中的大部分都间接继承自DependencyObject类,最明显的例子就是元素。
- 定义依赖项属性
他是DeoendencyProperty类的实例。属性信息应该始终保持可用,甚至可能需要在多个类之间共享这些信息(在WPF元素中这是十分普遍的)。因此,必须将DependencyProperty对象定义为与其相关联的类的静态字段,例如:
public cliass FrameworkElement:UIElement,...
{
public static readonly DependencyProperty MarginProperty;
...
}
按照约定,定义依赖项属性的字段的名称是在普通属性的末尾加上单词“Property”,根据这种命名方式,可以从实际属性的名称中区分出依赖项属性的定义。字段的定义使用了readonly关键字,这意味着,只能在FrameworkElement类的静态构造函数中对齐进行设置
- 注册依赖项属性
这一步需要在任何使用属性的代码之前完成,因此必须在于其关联的类的静态构造函数中进行。
WPF去报DependencyProperty对象不能被直接实例化,因为DependencyProperty类没有共有的构造函数,相反,只能使用DepencyProperty.Register()方法创建DependencyProperty实例。WPF还确保在创建DependencyProperty对象后不能改变该对象,因为所有DependencyProperty成员都是只读的,他们的值必须作为Register()方法的参数来提供。
static FrameworkElement()
{
FrameworkProperyMetadata metadata=new FrameworkPropertyMetadata(new Thickness(),FrameworkPropertyMeadataPption.AffectsMeasure);
MarginProperty=DependencyProperty.Register("Margin",typeof(Thickness),typeof(FrameworkElement),metadata,new ValidateValuCallback(FrameworkElement.IsMarginValid));
}
注册依赖项属性需要经历两个步骤。首先创建FrameworkPropertyMetadata对象,该对象指示希望通过依赖项属性使用什么服务(如支持数据绑定、动画以及日志)。接下来通过调用DependencyProperty.Register()静态方法注册属性。
3. 添加属性包装器
public Thickness Margin
{
set{setValue(MarginProperty,value);}
get{return (Thickness)Getvalue(MarginProperty);}
}
有一个细节:依赖项属性尊徐严格的优先规则来确定他们的当前值,即使没有直接设置依赖项属性,他也可能已经有了数值,该数值可能由数据绑定、样式或动画提供的,也可能是通过元素树继承来的。不过,只要直接设置了属性值,设置的属性值就会覆盖所有其他影响