UWP基础教程 - XAML标记扩展

标记扩展(Markup Extensions)是一个被广泛使用的XAML语言概念。通过XAML标记扩展来设定属性值,从而可以让对象元素的属性具备更加灵活和复杂的赋值逻辑。 本文将详细介绍Windows 10 UWP开发中XAML标记扩展基础概念和使用方法。常用的XAML标记扩展功能包括:

  1. Binding(绑定)标记扩展, 在XAML载入时,将数据绑定到XAML对象;
  2. StaticResource(静态资源)标记扩展, 实现引用数据字典(ResourceDictionary)中定义的静态资源;
  3. ThemeResource (主题资源)标记扩展,表示系统主题的静态资源;
  4. TemplateBinding(模板绑定)标记扩展, 实现在XAML页面中,对象模板绑定调用;
  5. RelativeSource(绑定关联源)标记扩展,实现对特定数据源绑定;

XAML标记扩展语法格式:

<元素对象 对象属性=”{扩展标记 扩展标记属性 = 扩展属性值}” />

Binding

<TextBox Text=”{Binding Path=UserName}”/>

以上代码中,第一行通过使用Binding标记扩展的Path属性将UserName绑定到元素对象TextBox的Text依赖属性中,使文本内容在运行时动态显示到客户端。

StaticResource

来看一个具体的例子

<Button ToolTipService.ToolTip="陈仁松XAML教程">
    <TextBlock Style="{StaticResource TextBlockStyle1}" Text="{Binding Source={StaticResource Test},Path=Text}"/>
</Button>

这个例子有三处使用了XAML代码,一处是StaticResource,另一处是Binding ,以及Binding里面的嵌套StaticResource,这种嵌套的语法叫做嵌套扩展,TextBlock元素的Text属性的值为{}中的结果,当XAML编译器看到{}时,把大括号中的内容解释为XAML标记扩展。

ThemeResource 使用根据当前处于活动状态的主题检索不同资源的附加系统逻辑,通过计算对某个资源的引用来为任何 XAML 属性提供值。 与 {StaticResource} 标记扩展类似,资源在 ResourceDictionary 中定义,并且 ThemeResource 用法引用 ResourceDictionary 中的该资源的键。

<ResourceDictionary x:Key="Default">
    <SolidColorBrush x:Key="ApplicationPageBackgroundThemeBrush" Color="#FF000000" />
    <SolidColorBrush x:Key="SystemControlBackgroundAccentBrush" Color="{ThemeResource SystemAccentColor}" />
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
    <SolidColorBrush x:Key="ApplicationPageBackgroundThemeBrush" Color="{ThemeResource SystemColorWindowColor}" />
    <SolidColorBrush x:Key="SystemControlBackgroundAccentBrush" Color="{ThemeResource SystemColorButtonFaceColor}" />
</ResourceDictionary>

以上代码包括了Default主题以及HighContrast主题的定义,如果你引用了某个系统资源,并且希望它发生更改以响应主题更改,则应当使用 ThemeResource 进行该引用。 TemplateBinding 相比前面三种标记,TemplateBinding标记扩展使用具有局限性,必须应用于ControlTemplate中,否则XAML将解析报错。 RelatvieSource RelatvieSource标记扩展是较为特殊的一个标记扩展。 在前面的代码中,我们使用了ElementBinding元素绑定一个对象属性到另外一个对象属性。值得留意的是,ElementBinding元素绑定只有在源对象被命名后才能正常使用,而对RelativeSource则允许绑定未命名源对象属性到目标对象属性。  Self模式

<Binding RelativeSource="{RelativeSource Self}" .../>

<object property="{Binding RelativeSource={RelativeSource Self} ...}" .../>

RelativeSource使用Self模式时, 目标对象将作为源对象绑定到自身。这个模式可以实现同一对象元素不同属性之间的绑定操作。例如:

<TextBox Text="{Binding Path=UserName}" ToolTipService.ToolTip="{Binding Text, RelativeSource={RelativeSource Self}}" />

以上代码,附加属性ToolTipService.ToolTip使用RelativeSource标记扩展绑定控件自身Text属性,作为提示信息显示在客户端。

TemplatedParent模式

<Binding RelativeSource="{RelativeSource TemplatedParent}" .../>

<object property="{Binding RelativeSource={RelativeSource TemplatedParent} ...}" .../>

RelativeSource使用TemplatedParent模式时, 仅在控件模板(ControlTemplate)或者数据模板(DataTemplate)下有效。不同的模板,将返回不同类型的绑定结果。例如,在一个 ListBox数据模板(DataTemplate)中应用RelativeSource的TemplatedParent模式,则会返回 ContentPresenter模板内容到对应数据模板中。TemplatedParent模式可以帮助开发人员绑定模板中的属性值到目标对象属性。例如:

<Style TargetType="local:Calendar">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:Calendar">
                <Grid>
                    <TextBlock Text="{Binding Path=Namer,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" />
                                <TextBlock Text="{TemplateBinding Namer}" />
                    ......
</Style>

在控件模板(ControlTemplate)中使用RelativeSource的TemplatedParent模式,”Binding RelativeSource={RelativeSource TemplatedParent}}“等价于”{TemplateBinding}"标记扩展。   两者不同在于,TemplateBinding仅支持单向(One-Way)绑定,而RelativeSource标记扩展支持双向(Two-Way)绑定,这个功能在创建自定义控件模板时特别有用。

XAML本身也定义了一些内置标记扩展,这些包括:x:Nullx:Typex:Staticx:Array

  1. x:Null是最简单的标记扩展,作用就是把目标属性设置为Null。例如:
<object>
  <object.property>
    <x:Null />
  </object.property>
</object>

再看一个具体的例子,下面代码是将TextBlock背景设置为空;

<TextBlock Background = "{x:Null}"/>
  1. x:Type在XAML中取对象的类型,类似于C#的typeof,这种操作发生在编译的时候;
  2. x:Static是用来把某个对象中的属性或域的值赋给目标对象的相关属性;
  3. x:Array表示一个.Net数组,x:Array元素的子元素都是数组元素,它必须和x:Type一起使用,用于定义数组类型;

本文就介绍到这里,有什么问题欢迎留言讨论。