属性值的继承
属性值继承(简称属性继承)与传统的面向对象继承不同,它是指属性值可以沿着元素树向下传递的过程。
例:在Window元素上设置属性
<Window x:Class="Test.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF揭秘" SizeToContent="WidthAndHeight"
FontSize="30" FontStyle="Italic" Background="OrangeRed">
<StackPanel>
<Label FontWeight="Bold" FontSize="20" Foreground="White">
WPF揭秘(版本3.0)
</Label>
<Label>(C)2006 SAMS 出版集团</Label>
<Label>已安装的章节:</Label>
<ListBox>
<ListBoxItem>第一章</ListBoxItem>
<ListBoxItem>第二章</ListBoxItem>
</ListBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button MinWidth="75" Margin="10">Help</Button>
<Button MinWidth="75" Margin="10">OK</Button>
</StackPanel>
<StatusBar>您已经注册了本产品。</StatusBar>
</StackPanel>
</Window>
下图展示了以显式方式设置Window元素的FontSize和FontStyle依赖属性后,整个窗体的变化情况。
为这两个属性设置的值将会沿着元素树向下传递,并被相应的子元素继承(即将子元素的对应属性也被设定为这个值)。上例中,Button、Label和ListBoxItem都受到了影响,但由于第一个Label显式设置了FontSize,从而其字体大小未受影响。值得注意的是,StatusBar中的文本并没有受到这两个值的影响,尽管它与其它控件相同,也包含这两个属性。由于以下两种原因,属性值的继承显得有些微妙:
(1)并不是所有的依赖属性都参与属性值的继承(依赖属性可以通过向DependencyProperty.Register传递FrameworkPropertyMatadataOptions.Inherits来选择是否参与继承)
(2)可能存在更高优先级的属性设定源(稍后解释)
StatusBar显示的结果由第二种原因导致的。一些如StatusBar、Menu和Tooltip控件的内部将它们的字体属性设定为匹配当前系统的设置。这种结果有些令人迷惑,因为这样的控件阻止了继承属性值沿着元素树继续传递。例如,当我们在StatusBar中加入一个Button作为其逻辑子元素,那么Button的FontSize和FontStyle都将保持默认值,这与处于StatusBar之外的那些Button不同。
属性值继承本来是用来操作元素树的,但是它也可以用于在其它情境。例如,属性值可以传递到某个XML意义上的子元素,而这个子元素并非逻辑树或视觉树的子元素。这些伪子元素可以是某个元素的触发器,也可是任意属性值,只要它是一个从Freezable派生的对象就可以。(暂不明)