1、标记扩展
对大多数属性而言,XAML属性语法可以工作的非常好。但是有些情况下,不可能硬编码属性值。例如,可能希望将属性值设置为一个已经存在的对象,或者可能希望通过将一个属性绑定到另外一个控件来动态地设置属性值。这两种情况都需要使用标记扩展——一种以非常规的方法设置属性的专门语法。
标记扩展可用来嵌套标签或XML特性中(用于XML特性的情况更常见)。当用在特性中时,它们总是被花括号{}包围起来。例如,下面的标记演示了如何使用标记扩展,它允许引用另外一个类中的静态属性:
1 <Button Foreground="{x:Static SystemColors.ActiveCaptionBrush}"></Button>
标记扩展使用{标记扩展类 参数}语法。在上述的示例中,标记扩展是StaticExtension类(根据约定,在引用扩展类时可以省略最后一个单词Extension)。x前缀指示在XAML名称空间中查找StaticExtension类。还有一些标记扩展是WPF名称空间的一部分,它们不需要x前缀。
所有标记扩展都由继承自System.Windows.Markup.MarkupExtension基类的类实现。MarkupExtension基类十分简单——它提供了一个简单的ProvideValue()方法类获取所期望的数值。换句话说,当XAML解析器遇到上述语句时,它将创建StaticExtension类的一个实例,然后调用ProvideValue()方法获取静态对象。最后找到按钮的Foreground属性。
2、附加属性
除普通属性外,XAML还包括附加属性(attached property)的概念——附加属性是可用于多个控件但在另外一个类中定义的属性。在WPF中,附加属性常用语控件布局。
每个控件都有各自固有的属性。当在容易中方式控件时,根据容器的类型控件会获得额外特征(例如,如果在网格中放置一个文本框,就需要选择文本框放在网格控件中的哪个单元格中),使用附加属性设置这些附加的细节。
附加属性始终使用包含两个部分的命名格式:定义类型.属性名。这种包含两部分的命名语法使XAML解释器能区分开普通属性和附加属性。
如下代码中,Grid.Row=“0”就是属于附加属性。
1 <TextBox VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="10,10,13,10" TextWrapping="Wrap" Grid.Row="0" FontFamily="Verdana" FontSize="24"> 2 [Please Question here!] 3 </TextBox> 4 5 <Button VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,0,0,20" Grid.Row="1" Width="127" Height="23" Name="btnAnswer" Click="btnAnswer_Click"> 6 Ask the Eight Ball 7 </Button> 8 <TextBox Grid.Row="2" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" TextWrapping="Wrap" IsReadOnly="True" Margin="10,10,13,10" FontFamily="Verdana" FontSize="24" Foreground="Green"> 9 [Answer will appear here!] 10 </TextBox>