WPF中的Dependency Property(3)

在这一个Post中,我们将重点关注Dependency Property的属性值继承。

属性值继承指的是属性值自顶向下沿着元素树传递,从下面的示例中,我们很快就能理解什么是属性值继承。

<Window x:Class="Demo.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ResizeMode="NoResize"

    Title="Window1" Height="300" Width="300" FontSize="20" FontStyle="Italic">

    <StackPanel>

        <Label Content="I'm a Label!"/>

        <Button Content="I'm a Button!"/>

        <StatusBar>I'm a StatusBar!</StatusBar>

    </StackPanel>

</Window>

Window中设置了FontSize="20"FontStyle="Italic"LabelButton没有设置FontSizeFontStyle,但运行起来后可以看到,它们同样拥有了和Window一样的FontSizeFontStyle,这就是属性值继承,即LabelButton沿着元素树从Window那里继承了部分属性值。

有趣的是,StackPanel根本连FontSizeFontStyle都没有,怎么继承?显然,将FontSizeFontStyle借由元素树来传递的做法,比我们想像更精细,而不是使用简单的“父传子”机制。尽管StackPanel没有FontSizeFontStyle,依然可以让孩子们获得需要被继承的属性值。

如果我们显式的去设定Button或者LabelFontSizeFontStyle,那么,我们可以看到,它们将以自己设定的方式去显示,而不再从元素树中继承了,这是为什么呢?这是因为,如果未设定属性值,它们将以默认值显示;而从元素树中继承属性值的优先权比默认值要高,而“对元素本身的设定”具有最高的优先权。关于这其中的优先权,我们将在下一个Post中讲解。

另外,我们会发现一个问题,为什么StatusBar未设定FontSizeFontStyle,却不从Window那里继承属性值呢?

属性值的继承行为是由以下两种因素决定的:

1)    并不是每个Dependency Property都参与属性值继承(从内部来讲,只有在Register Dependency Property时设定了“metadata.Inherits = true”的Dependency Property才能有继承权限);

2)    有其他优先权更高的源进行了属性值设定;

因此,StatusBar(还有MenuTooltip)控件满足了第二个因素才没有从Window那里继承属性值。它是从桌面的主题样式那里获得了属性值,而从桌面的主题样式处获取要比一般的属性值继承的优先权高。这样做的好处是用户可以从控制面板中控制它们的字体,从而让画面都具有一样的风格,对于用户来说很熟悉。

StatusBar控件,它会阻止继承继续沿着元素树向下传递。例如,如果我们将另一个Button作为StatusBar控件的子元素,它的FontSizeFontStyle将是从桌面的主题样式那里获得的值,而不能从Window那里继承属性值(被StatusBar控件阻止了或者“吞噬”了)。

<StatusBar>

    <Button Content="Haha"/>

</StatusBar>

posted on 2009-01-06 16:43  xirihanlin  阅读(888)  评论(1编辑  收藏  举报