闲话WPF之九(Dependency属性 [1] )
WPF引入了一种新的属性:Dependency属性。Dependency属性的应用贯串在整个WPF当中。Dependency属性根据多个提供对象来决定它的值。并且是及时更新的。提供对象可以是动画,不断地改变它的值。也可以是父元素,它的属性值被继承到子元素。毫无疑问,Dependency属性最大的特点就是内建的变化通知功能。提供Dependency属性功能主要是为了直接从声明标记提供丰富的功能。WPF声明的友好设计的关键是大量的使用属性。如果没有Dependency属性,我们将不得不编写大量的代码。关于WPF的Dependency属性,我们将重点研究如下三个方面:
1、变化通知功能:属性的值被改变后,通知界面进行更新。
2、属性值的继承功能:子元素将继承父元素中对应属性名的值。
3、支持多个提供对象:我们可以通过多种方式来设置Dependency属性的值。
先看如何实现一个标准的Dependency属性。
public class Button : ButtonBase
{
// The dependency property
public static readonly DependencyProperty IsDefaultProperty;
static Button()
{
// Register the property
Button.IsDefaultProperty = DependencyProperty.Register(“IsDefault”, typeof(bool), typeof(Button),
new FrameworkPropertyMetadata(false,
new PropertyChangedCallback(OnIsDefaultChanged)));
…
}
// A .NET property wrapper (optional)
public bool IsDefault
{
get { return (bool)GetValue(Button.IsDefaultProperty); }
set { SetValue(Button.IsDefaultProperty, value); }
}
// A property changed callback (optional)
private static void OnIsDefaultChanged(
DependencyObject o, DependencyPropertyChangedEventArgs e) { … }
…
}
在上面的实现代码中,System.Windows.DependencyProperty类表示的静态字段IsDefaultProperty才是真正的Dependency属性。为了方便,所有的Dependency属性都是公有、静态的,并且还有属性后缀。通常创建Dependency属性可用静态方法DependencyProperty.Register。参数的属性名称、类型、使用这个属性的类。并且可以根据重载的方法提供其他的通知事件处理和默认值等等。这些相关的信息可参考FrameworkPropertyMetadata类的多个重载构造函数。
最后,实现了一个.NET属性,其中调用了从System.Windows.DependencyObject继承的GetValue、SetValue方法。所有具有Dependency属性的类都肯定会继承这个类。GetValue方法返回最后一次设置的属性值,如果还没有调用一次SetValue,返回的将是Register方法所注册的默认值。而且,这种.NET样式的属性封装是可选的,因为GetValue/SetValue方法本身是公有的。我们可以直接调用这两个函数,但是这样的封装使代码更可读。