依赖项属性
依赖项属性使用更高的保存机制,支持附加功能,如更改通知,属性继承。依赖想属性也是WPF许多重要功能的基础,包括动画,数据绑定,样式等。依赖项属性的使用和普通.net属性一样。
只能为依赖对象(继承自DependencyObject的类)添加依赖项属性。
依赖项属性定义约定:普通属性末尾加上Property
定义依赖项属性的步骤
1.定义表示属性的对象,他是DependencyProperty类的实例
public static readonly DependencyProperty MarginProperty;
2.注册依赖项属性
DependencyProperty对象不能直接被实例化,因为DependencyProperty类没有公有的构造函数。只能使用DependencyProperty.Register()静态方法,创建DependencyProperty对象。创建后的对象不能改变,因为DependencyProperty的成员都是只读的。
首先创建FrameworkPropertyMetadata对象,该对象指示希望通过依赖项属性使用什么服务(支持数据绑定,动画,日志)。接下来通过调用DependencyProperty.Register()静态方法注册属性。在这一步中,提供一下几个要素
v 属性名(在该例中是Margin)
v 属性使用的数据类型(该例是Thickness)
v 拥有该属性的类型(FrameworkElement类)
v 一个具有附加属性设置的FrameworkPropertyMetadata 对象,该要素可选
v 一个用于验证属性的回调函数,该要素可选。
FrameworkPropertyMetadata metadata =
new FrameworkPropertyMetadata(new Thickness(), FrameworkPropertyMetadataOptions.AffectsMeasure);
MarginProperty=DependencyProperty.Register(“Margin”,typeof(Thickness),typeof(FrameworkElement),metadata,new ValidateValueCallback(FrameworkElement.IsMarginValid));
添加属性包装器
Public Thickness Margin
{
Set{SetValue(MarginProperty,value);}
Get{return (Thickness)GetValue(MarginProperty);}
}
共享依赖项属性
TextBlock.FontFamilyProperty=TextElement.FontFamilyPropery.AddOwer(typeof(TextBlock));
附加的依赖项属性
附加属性是一种依赖项属性,为了定义附加属性,需要调用RegisterAttached()方法,而不是使用Register()方法。
附加属性不需要封装属性
使用静态方法
例如Grid.Row附加属性。
Public static int GetRow(UIElement element)
{
If(element==null)
{
}
Return (int) element.GetValue(Grid.RowProperty);
}
在定义任何类型的属性时,都需要面对错误设置属性的可能性。
WPF提供两种方法来阻止非法值:
ValidateValueCallback:该回调函数可接受或拒绝新值,可作为Register()一个参数
CoerceValueCallback:该回调函数可将新值更改为更能被接受的值。使用该回调函数可在FrameworkPropertyMetadata对象时作为构造函数的参数。
设置依赖项属性时,这些内容的过程:
首先,CoerceValueCallback有机会修改提供的值。
接下来激活方法ValidateValueCallback。
最后,如果强两个阶段都获得成功,就会触发PeopertyChangedCallback方法,此时,如果希望为其他类提供通知,可以引发更改时间。
验证回调函数
MarginProperty=DependencyProperty.Register(“Margin”,typeof(Thickness),typeof(FrameworkElement),metadata,new ValidateValueCallback(FrameworkElement.IsMarginValid));
作为Register函数的一个参数。
验证回调函数的限制,他们必须是一个静态方法而且无权访问正在被验证的对象。
强制回调
通过FrameworkPropertyMetadata对象使用CoerceValueCallback回调函数。例子
FrameworkPropertyMetadata medata=new FrameworkPropertyMetadata ();
medata.CoerceValueCallback=new CoerceValueCallback(参数)