添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

条件 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 编程
  •