将所有的属性都设置为依赖属性并不总是正确的解决方案,具体取决于其应用场景。有时,使用私有字段实现属性的典型方法便能满足要求。MSDN中给出了下面几种应用依赖属性的场景:
1. 希望可在样式中设置属性。
3. 希望可使用动态资源引用设置属性。
5. 希望属性可进行动画处理。
6. 希望属性系统在属性系统、环境或用户执行的操作或者读取并使用样式更改了属性以前的值时报告。
7. 希望使用已建立的、WPF 进程也使用的元数据约定,例如报告更改属性值时是否要求布局系统重新编写元素的可视化对象。
目前我使用最多的场景是前三条,下面是一个典型的依赖属性在数据绑定上的应用场景:
界面上有A、B两个图片,大小一样,我们需要在改变图片A大小的时候,同时也改变图片B的大小,让他们的大小总保持一致。按照通常的做法我们应该怎么做?
我们需要在图片A的SizeChanged事件中添加处理图片B的方法。把图片A的Size赋给图片B。这么一个简单的功能需要这么一段代码来做是不是有点繁琐,若此类需求更多,则你需要处理的事件将更多。
imageB.DataContext = imageA; imageB.SetBinding(Image.WidthProperty,"Width"); imageB.SetBinding(Image.HeightProperty,21)">"Height");
怎么样,够简洁吧!这段话大致的意思就是:
1. 将ImageB的参与数据绑定时的数据上下文为ImageA,即ImageB上绑定的数据都到ImageA上找;
2. 将ImageB的宽高通过SetBinding的方法绑定到"Width"及"Height"两个属性上。这两个属性的值在哪里找,就在ImageB的DataContext中找,在这里就是ImageA的"Width"及"Height"。
这样就将ImageA和ImageB的"Width"及"Height"绑定在一起,其中一个图片的"Width"及"Height"发生改变时,另一个图片的Size也会相应的发生改变。
在类上实现属性时,只要该类派生自 DependencyObject,便可以选择使用 DependencyProperty 标识符来标示属性,从而将其设置为依赖属性。其语法如下:
public static DependencyProperty TextProperty = DependencyProperty.Register("Text",//属性名称 typeof(string),//属性类型 typeof(TestDependencyPropertyWindow ),//该属性所有者,即将该属性注册到那个类上 new PropertyMetadata("")); //属性默认值 public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty,value); } }
可以看到其与普通属性的主要区别在于:
1. 字段必须为static,且类型为DependencyProperty,字段名需遵守命名约定,即后缀为Property;
2. 字段的修饰符须设置为Public,否则在外部不能通过SetBinding方法,绑定此属性的值;
3. 字段的值通过DependencyProperty.Register来设置,各参数的说明详见代码中的说明;
4. 设置属性值时,通过SetValue、GetValue而不是Set、Get。
通过上面的方法我们便在CustomSape类上自定义了一个依赖属性“Text”,然后我们便可以像使用系统自带的依赖属性一样,使用这个属性。
总之,依赖属性是WPF的一个重要特性,可以用简单的几句话,实现原来Winform实现起来非常繁琐的功能。具体什么时候使用依赖属性、什么时候使用普通属性,就要看具体的使用情况,并参照MSDN给出的7个应用场景。