条件 XAML 提供在 XAML 标记中使用
   
    ApiInformation.IsApiContractPresent
   
   方法的一种途径。 可以在 API 存在的情况下在标记中设置属性和实例化对象,无需使用代码隐藏。 它选择性地分析元素或属性来确定它们在运行时是否可用。 条件语句在运行时进行评估。如果评估为
   
    true
   
   ,则会对使用条件 XAML 标记进行限定的元素进行分析;否则会忽略它们。
  
  
   条件 XAML 从 Creators Update(版本 1703,内部版本 15063)开始提供。 若要使用条件 XAML,Visual Studio 项目的最低版本必须设置为内部版本 15063 (Creators Update) 或更高版本,且目标版本必须设置为比最低版本更高的版本。 请参阅
   
    版本自适应应用
   
   ,详细了解如何配置 Visual Studio 项目。
  
  
   若要使用低于内部版本 15063 的最低版本创建版本自适应应用,则必须使用
   
    版本自适应代码
   
   ,而不是 XAML。
  
  
   有关 ApiInformation 和 API 协定的重要背景信息,请参阅
   
    版本自适应应用
   
   。
  
  
   条件命名空间
  
  
   若要在 XAML 中使用条件方法,首先必须在页面顶部声明条件
   
    XAML 命名空间
   
   。 下面介绍条件命名空间的伪代码示例:
  
  xmlns:myNamespace="schema?conditionalMethod(parameter)"
条件命名空间可以分为两部分,用“?”分隔符分隔。
分隔符前面的内容指示命名空间或架构含有被引用的 API。
分隔符“?”后的内容表示条件方法,该方法确定是将条件命名空间评估为 true 还是 false。
在大多数情况下,架构将是默认的 XAML 命名空间:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
条件 XAML 支持以下条件方法:
IsApiContractPresent(ContractName, VersionNumber)
IsApiContractNotPresent(ContractName, VersionNumber)
IsTypePresent(ControlType)
IsTypeNotPresent(ControlType)
IsPropertyPresent(ControlType, PropertyName)
IsPropertyNotPresent(ControlType, PropertyName)
我们将在本文后面的部分中进一步讨论这些方法。
我们建议你使用 IsApiContractPresent 和 IsApiContractNotPresent。 其他条件在 Visual Studio 设计体验中不完全受支持。
创建命名空间并设置一个属性
在此示例中,如果在 Fall Creators Update 或更高版本上运行应用,将显示“Hello, Conditional XAML”作为文本块的内容;如果在以前的版本上运行,则默认显示无内容。
首先,使用前缀“contract5Present”定义自定义命名空间并使用默认 XAML 命名空间 (https://schemas.microsoft.com/winfx/2006/xaml/presentation) 作为含有 TextBlock.Text 属性的架构。 若要使其成为一个条件命名空间,请在架构后添加“?” 分隔符。
然后定义在运行 Fall Creators Update 或更高版本的设备上返回 true 的条件。 使用 ApiInformation 方法 IsApiContractPresent 来检查 UniversalApiContract 的第 5 个版本。 UniversalApiContract 版本 5 和 Fall Creators Update (SDK 16299) 一起发布。
xmlns:contract5Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"
定义命名空间后,将命名空间前缀添加到 TextBox 的 Text 属性的前面,将它限定为应该在运行时进行条件性设置的属性。
<TextBlock contract5Present:Text="Hello, Conditional XAML"/>
下面是完整的 XAML。
    x:Class="ConditionalTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:contract5Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock contract5Present:Text="Hello, Conditional XAML"/>
    </Grid>
</Page>
在 Fall Creators Update 上运行此示例时,显示文本“Hello, Conditional XAML”;在 Creators Update 上运行时,不显示文本。
条件 XAML 可以让你改为在标记中执行可针对代码执行的 API 检查。 下面介绍此检查的等效代码。
if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 5))
    textBlock.Text = "Hello, Conditional XAML";
请注意,即使 IsApiContractPresent 方法带有一个表示 contractName 参数的字符串,也不应将它放在 XAML 命名空间声明的引号 (" ") 中。
使用 if/else 条件
在上面的示例中,仅当在 Fall Creators Update 上运行应用时设置 Text 属性。 但是,当它在 Creators Update 上运行时,如果你想要显示不同的文本,应该怎么做? 可以尝试在不使用条件限定符的情况下设置 Text 属性,如下所示。
<!-- DO NOT USE -->
<TextBlock Text="Hello, World" contract5Present:Text="Hello, Conditional XAML"/>
当它在 Creators Update 上运行时,这会有效;但在 Fall Creators Update 上运行时,你会收到错误消息,指出 Text 属性已设置多次。
当应用在不同版本的 Windows 10 上运行时,若要设置不同的文本,你需要另一个条件。 条件 XAML 提供每种受支持的 ApiInformation 方法的反转,让你创建类似这样的 if/else 条件方案。
如果当前设备包含指定合同和版本号,IsApiContractPresent 方法会返回 true。 例如,假设在 Creators Update 上运行应用,它具有通用 API 协定第 4 版。
对 IsApiContractPresent 的不同调用会产生以下结果:
IsApiContractPresent(Windows.Foundation.UniversalApiContract, 5) = false
IsApiContractPresent(Windows.Foundation.UniversalApiContract, 4) = true
IsApiContractPresent(Windows.Foundation.UniversalApiContract, 3) = true
IsApiContractPresent(Windows.Foundation.UniversalApiContract, 2) = true
IsApiContractPresent(Windows.Foundation.UniversalApiContract, 1) = true。
IsApiContractNotPresent 返回 IsApiContractPresent 的反转。 调用 IsApiContractNotPresent 会产生以下结果:
IsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 5) = true
IsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 4) = false
IsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 3) = false
IsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 2) = false
IsApiContractNotPresent(Windows.Foundation.UniversalApiContract, 1) = false
若要使用反转条件,可以创建第二个使用 IsApiContractNotPresent 条件的条件 XAML 命名空间。 在这里,其中包含前缀“contract5NotPresent”。
xmlns:contract5NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,5)"
xmlns:contract5Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"
定义两个命名空间后,可以将 Text 属性设置两次,前提是在它们前面添加限定符,确保在运行时仅使用一个属性设置,如下所示:
<TextBlock contract5NotPresent:Text="Hello, World"
           contract5Present:Text="Hello, Fall Creators Update"/>
下面介绍了设置按钮背景的另一个示例。 亚克力材料功能从 Fall Creators Update 开始提供,因此当在 Fall Creators Update 上运行应用时,你将为背景使用亚克力。 它在更早的版本中不可用,因此在这些情况下,要将背景设置为红色。
<Button Content="Button"
        contract5NotPresent:Background="Red"
        contract5Present:Background="{ThemeResource SystemControlAcrylicElementBrush}"/>
创建控件和绑定属性
到目前为止,你已了解如何使用条件 XAML 设置属性,但你也可基于在运行时可用的 API 协定条件性地实例化控件。
在这里,当在控件可用的 Fall Creators Update 上运行应用时,对 ColorPicker 进行实例化。 ColorPicker 在 Fall Creators Update 之前不可用,因此在较早的版本上运行应用时,使用 ComboBox 为用户提供简化的颜色选项。
<contract5Present:ColorPicker x:Name="colorPicker"
                              Grid.Column="1"
                              VerticalAlignment="Center"/>
<contract5NotPresent:ComboBox x:Name="colorComboBox"
                              PlaceholderText="Pick a color"
                              Grid.Column="1"
                              VerticalAlignment="Center">
可以使用具有不同形式的 XAML 属性语法的条件限定符。 在这里,使用用于 Fall Creators Update 的属性元素句法和用于较早版本的属性句法设置矩形的 Fill 属性。
<Rectangle x:Name="colorRectangle" Width="200" Height="200"
           contract5NotPresent:Fill="{x:Bind ((SolidColorBrush)((FrameworkElement)colorComboBox.SelectedItem).Tag), Mode=OneWay}">
    <contract5Present:Rectangle.Fill>
        <SolidColorBrush contract5Present:Color="{x:Bind colorPicker.Color, Mode=OneWay}"/>
    </contract5Present:Rectangle.Fill>
</Rectangle>
将属性绑定到取决于条件命名空间的另一个属性时,必须对这两个属性使用相同的条件。 在这里,colorPicker.Color 取决于“contract5Present”条件命名空间,因此必须将“contract5Present”前缀放在 SolidColorBrush.Color 属性的前面。 (或者将“contract5Present”前缀放在 SolidColorBrush 的前面,而不是放在 Color 属性的前面。)否则会出现编译时间错误。
<SolidColorBrush contract5Present:Color="{x:Bind colorPicker.Color, Mode=OneWay}"/>
下面是演示这些方案的完整 XAML。 此示例中包含一个矩形以及一个让你设置矩形颜色的 UI。
在 Fall Creators Update 上运行应用时,使用 ColorPicker 让用户设置颜色。 ColorPicker 在 Fall Creators Update 之前不可用,因此在较早的版本上运行应用时,使用组合框为用户提供简化的颜色选项。
    x:Class="ConditionalTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:contract5Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"
    xmlns:contract5NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,5)">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Rectangle x:Name="colorRectangle" Width="200" Height="200"
                   contract5NotPresent:Fill="{x:Bind ((SolidColorBrush)((FrameworkElement)colorComboBox.SelectedItem).Tag), Mode=OneWay}">
            <contract5Present:Rectangle.Fill>
                <SolidColorBrush contract5Present:Color="{x:Bind colorPicker.Color, Mode=OneWay}"/>
            </contract5Present:Rectangle.Fill>
        </Rectangle>
        <contract5Present:ColorPicker x:Name="colorPicker"
                                      Grid.Column="1"
                                      VerticalAlignment="Center"/>
        <contract5NotPresent:ComboBox x:Name="colorComboBox"
                                      PlaceholderText="Pick a color"
                                      Grid.Column="1"
                                      VerticalAlignment="Center">
            <ComboBoxItem>Red
                <ComboBoxItem.Tag>
                    <SolidColorBrush Color="Red"/>
                </ComboBoxItem.Tag>
            </ComboBoxItem>
            <ComboBoxItem>Blue
                <ComboBoxItem.Tag>
                    <SolidColorBrush Color="Blue"/>
                </ComboBoxItem.Tag>
            </ComboBoxItem>
            <ComboBoxItem>Green
                <ComboBoxItem.Tag>
                    <SolidColorBrush Color="Green"/>
                </ComboBoxItem.Tag>
            </ComboBoxItem>
        </contract5NotPresent:ComboBox>
    </Grid>
</Page>
UWP 应用指南
使用 API 合约动态检测功能
使用扩展 SDK 编程