WPF学习笔记5. DependencyProperty
2010-10-11 16:08:41 来源:本站整理4. 多提供程序优先级
WPF 允许我们可以在多个地方设置依赖属性的值,这的确很方便,但也问题也不少。比如下面的例子中,我们在三个地方设置了按钮的背景颜色,只是最后哪个会起作用呢?
<Button x:Name="button1" Background="Red"> <Button.Style> <Style TargetType="{x:Type Button}"> <Setter Property="Background" Value="Green"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="Blue" /> </Trigger> </Style.Triggers> </Style> </Button.Style> Click </Button>
确切的答案是 "<Button Background='Red'>" 起作用了,为什么呢?因为 WPF 内在的优先级规则决定了 "本地值" 优先级别最高。
本地值 > 样式触发器 > 模板触发器 > 样式设置程序 > 主题样式触发器 > 出题样式设置程序 > 属性值继承 > 默认值
这样的一个过程被称之为 "基础值判断"。我们需要特别说名一下,所谓本地值是指我们直接或间接调用了 DependencyObject.SetValue,也就是显示设置了依赖属性的值。我们可以用下面这样的代码清除本地值设置。
this.button1.ClearValue(Button.BackgroundProperty);
虽然我们获取了基础值,但事情并没有结束,接下来有几个更厉害的选手出场,他们的优先级别更高,依赖属性必须一一过关才算最后确定下来。
基础值判断 -> 表达式计算 -> 应用动画 -> 限制(Coerce) -> 验证 -> 最终结果
(1) 验证是指我们注册依赖属性所提供的 ValidateValueCallback 委托方法,它最终决定了属性值设置是否有效;
(2) 限制则是注册时提供的 CoerceValueCallback 委托,它负责验证属性值是否在允许的限制范围之内,比如大于等于 9 小于等等 100;
(3) 动画是一种特殊行为,它的优先级高于基础设置也能理解;
(4) 如果依赖属性值是计算表达式 (System.Windows.Expression,比如前面示例中的绑定语法),那么 WPF 会尝试 "计算" 表达式的结果。
(5) 基础值就是上面提供的那些显示设置,它的优先级比较好确定。
5. 附加属性
附加属性是一种特殊的依赖属性,它看上去颇为古怪,尤其是对我们这些熟悉了面向对象规则的程序员而言。看下面的例子。
<DockPanel> <CheckBox DockPanel.Dock="Top">Hello</CheckBox> </DockPanel>
DockPanel.Dock 是 DockPanel 中定义的依赖属性,但却出现在子元素的声明上,看上去很诡异。
<StackPanel TextElement.FontSize="30" TextElement.FontStyle="Blod"> <Button>Help</Button> <Button>OK</Button> </StackPanel>
TextElement.FontSize, TextElement.FontStyle 既不属于 StackPanel,也不属于 Button,但却能完成元素树的字体定义。
附加属性严格来说是一个 XAML 概念,依赖属性是 WPF 概念。附加属性通常用于界面元素的布局设置。这样一种特殊的扩展机制,使得父元素可以将一些自定义设置传递给所有子元素,而无需要求子元素必须具备相同的依赖属性。这种应用方式有点扩展方法的意思,初次接触时的确不太好理解。
赞助商链接