WPF中的Dependency Property(4)

Dependency Property(3)——属性值继承中,我们提到一些具有一定优先权的源,也就是属性值提供程序,它们到底有哪些呢?这就是我们在这个Post中要说的Dependency Property支持多个属性值提供程序。

WPF提供了强大的机制来保证多个提供程序设置Dependency Property的值,而这些提供 程序按照一定的流程、一定的优先权来进行设置。如果没有设计良好的机制来处理这些完全不同的属性值提供程序,这个系统就会变得混乱,属性值也会变得不稳定。

下图显示了设置Dependency Property的流程,WPF中的每一个Dependency Property也是按照这一流程最终计算出来它的值的。多亏了Dependency Property中的变化通知能力,这个流程才得以自动发生。

 

 

 

1.       第一步:判断基础值

大多数属性提供程序会影响属性的基础值。下面以优先权从高到低的顺序列出了可以设置大多数Dependency Property8个提供程序:

(1) 本地值                                                   (2) 样式触发器

(3) 模板触发器                                         (4) 样式设置程序

(5) 主题样式触发器                                (6) 主题样式设置程序

(7) 属性值继承                                         (8) 默认值

本地值,技术上指任何对DependencyObject.SetValue()的调用,常见的形式是在XAML或在过程式代码中的属性赋值。默认值指的是Dependency Property注册时使用的初始值,优先权最低。

这个优先顺序解释了Dependency Property(3)StatusBar控件的“特殊”。同样,如果我们设置Dependency Property (3)LabelFontSizeFontStyle,那么,它将不再从Window那里继承属性值,这是因为本地值比属性值继承的优先权高,本地值说了算,J

2.       第二步:计算

如果第一步中的值是表达式,那么WPF会执行一种特殊的演算步骤——把表达式转换为具体的结果。目前,表达式仅在使用动态资源或数据绑定时起作用。

3.       第三步:应用动画

对属性应用的动画胜过其他任何属性值提供程序——就连本地值也不是它的“对手”!

4.       第四步:限制

在所有属性值提供程序处理过之后,WPF将拿到一个几乎是终值的属性值。如果Dependency Property已经注册了CoerceValueCallback,还会把这个属性值传递给CoerceValueCallback委托,该回调函数依据自己的逻辑返回一个新的值。比如ProgressBar,会使用回调来限制叫作ValueDependency Property,保证其在最大值最小值范围内。

5.       第五步:验证

最后,如果Dependency Property已经注册了ValidateValueCallback,第四步中获得的值将被传入ValidateValueCallback委托。如果输入值有效,该回调函数必须返回true;否则返回false。返回false将会导致抛出一个异常,并使整个流程被取消。

走完这五步,Dependency Property的最终值也被确定下来。

提示:清除本地值

如果某个控件中的某个属性的值来自于样式(或者主题样式)的提供程序,在代码中一旦人为设定了值,那么它将不再从样式(或者主题样式)处获得值。如何才能让属性的值重新来自于样式(或者主题样式)呢?DependencyObject提供了这种机制,可以通过调用ClearValue()方法来实现。调用之后,会把本地值删除,重新计算基础值。

 

posted on 2009-01-08 09:43  xirihanlin  阅读(829)  评论(0编辑  收藏  举报