Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Условный КОД XAML предоставляет способ использования метода ApiInformation.IsApiContractPresent непосредственно в разметке XAML. Вы можете задать свойства на основе наличия контракта API на уровне ОС, не записывая код позади. Условные выражения вычисляются во время выполнения — элементы, помеченные условным тегом XAML, обрабатываются, если условие принимает значение true, и игнорируются в противном случае.
Начиная с Windows App SDK 2.0, можно также определить собственные условия, реализуя интерфейс IXamlCondition. Пользовательские условия позволяют включать или исключать разметку на основе состояния конкретного приложения, например флагов функций или параметров конфигурации. Дополнительные сведения см. в разделе Создание настраиваемых условий.
Для условного XAML требуется Windows 10 версии 1809 (сборка 17763) или более поздней версии, которая является минимальной версией ОС для приложений Windows App SDK.
Необходимые условия
- Проект Windows App SDK. Инструкции по настройке см. в разделе "Создание и запуск проекта WinUI 3".
- Знакомство с приложениями, адаптирующимися к версии и классом
ApiInformation.
Important
Встроенные условные методы используют методы ApiInformation, которые проверяют наличие контрактов API среда выполнения Windows (Windows.*) и типов, предоставляемых ОС. Эти проверки не применяются к элементам управления WinUI 3 (Microsoft.UI.Xaml.*), поскольку WinUI 3 поставляется вместе с вашим приложением через Windows App SDK, а не с операционной системой — каждый элемент управления WinUI 3, с которым собрано ваше приложение, всегда присутствует во время выполнения, независимо от того, какая сборка Windows 10/11 установлена на устройстве.
#if Директивы препроцессора тут тоже не помогают: они обрабатываются во время компиляции на основе целевого фреймворка, а не во время выполнения на основе ОС или фактически установленной версии Windows App SDK. Чтобы включать функцию в зависимости от версии Windows App SDK, с которой работает ваше приложение, проверяйте версию Windows App SDK на этапе сборки или используйте конструкцию try/catch при вызове API. Дополнительные сведения см. в адаптивном коде версии .
Дополнительные сведения о ApiInformation и контрактах API см. в статье Приложения с адаптацией к версии.
Условные пространства имен
Чтобы использовать условный метод в XAML, объявите условное пространство имен XAML в верхней части страницы:
xmlns:myNamespace="schema?conditionalMethod(parameter)"
Содержимое ? перед разделителем — пространство имен или схема. Содержимое после ? представляет собой условный метод, который определяет, вычисляется ли пространство имён как 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) |
Вы также можете использовать условие, которое вы определяете в приложении. Дополнительные сведения см. в разделе Создание настраиваемых условий
Note
Используйте IsApiContractPresent и IsApiContractNotPresent для максимального удобства на этапе разработки. Другие условные условия не полностью поддерживаются в интерфейсе разработки Visual Studio.
Задать свойство условно
В этом примере текст отображается в элементе TextBlock только если приложение работает под Windows 10 версии 1903 (обновление за май 2019 года, сборка 18362) или более поздней версии — такая проверка контракта имеет смысл, поскольку она относится к версии новее, чем минимально поддерживаемая версия 1809 в Windows App SDK.
Сначала определите условное пространство имен:
xmlns:contract8Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,8)"
Затем префикс свойства с помощью условного пространства имен:
<TextBlock contract8Present:Text="Hello, Conditional XAML"/>
Ниже приведена полная разметка:
<Page
x:Class="ConditionalTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:contract8Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,8)">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock contract8Present:Text="Hello, Conditional XAML"/>
</Grid>
</Page>
Эквивалентная проверка в коде программной части:
TextBlock textBlock = new TextBlock();
if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
{
textBlock.Text = "Hello, Conditional XAML";
}
Note
IsApiContractPresent Несмотря на то что принимает строку в качестве параметра имени контракта, её не заключают в кавычки в объявлении пространства имён XAML.
Так как минимальная поддерживаемая версия ОС для Windows App SDK — 1809 (UniversalApiContract версия 7), проверка версии контракта, равной 7 или ниже, в приложении Windows App SDK всегда даёт значение true и не даёт никакой полезной информации. Проверяйте только версии контракта выше 7.
Использование условий if/else
Чтобы задать разные значения в зависимости от контракта API, определите как положительные, так и отрицательные условные пространства имен:
xmlns:contract8NotPresent="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractNotPresent(Windows.Foundation.UniversalApiContract,8)"
xmlns:contract8Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,8)"
Затем задайте свойство дважды, каждый из которых имеет другой условный префикс. Применяется только один во время выполнения:
<TextBlock contract8NotPresent:Text="Hello, World"
contract8Present:Text="Hello, May 2019 Update or later"/>
Создание экземпляров элементов управления при определённых условиях
Note
Условное создание экземпляра элемента в зависимости от контракта API ОС — в отличие от условной установки свойства — это шаблон, характерный для UWP. Он не применяется к элементам управления WinUI 3.
В UWP этот шаблон позволяет вернуться к более старому Windows.UI.Xaml.Controls элементу управления, когда он был недоступен в ОС. В приложении Windows App SDK элементы управления WinUI 3 (Microsoft.UI.Xaml.Controls.*) передаются с приложением через Windows App SDK, а не с ОС. Каждый элемент управления, на который рассчитано ваше приложение, включая ColorPicker, гарантированно доступен во время выполнения, поэтому перед созданием его экземпляра не нужно проверять версию ОС.
Если вам нужно сделать использование элемента управления WinUI 3 или API зависимым от версии Windows App SDK, на которую ориентировано ваше приложение, выполняйте эту проверку во время сборки (задав минимальную версию пакета Windows App SDK) или оберните вызов во время выполнения в try/catch, а не используйте условный XAML.
Чтобы включить или исключить элементы на основе логики, определяемой приложением, например флагом функции, используйте настраиваемое условие.
Создать настраиваемые условия
Начиная с Windows App SDK 2.0, можно определить собственные условия и использовать их с синтаксисом условных пространств имен. Настраиваемое условие позволяет включать или исключать разметку на основе состояния конкретного приложения, например флагов функций, параметров конфигурации или возможностей устройства. Как и встроенные условные методы, пользовательские условия оцениваются при разборе XAML во время выполнения.
- Важные API: интерфейс IXamlCondition, метод IXamlCondition.Evaluate
![]()
Приложение WinUI 3 Gallery содержит интерактивные примеры элементов управления и функций WinUI. Получите приложение из Microsoft Store или просмотрите исходный код в GitHub.
Note
IXamlCondition заменяет интерфейс IXamlPredicate из экспериментальных выпусков Windows App SDK 2.0.
Реализовать условие
Чтобы создать условие, определите класс, производный от DependencyObject и реализующий интерфейс IXamlCondition. Средство синтаксического анализа XAML вызывает метод Evaluate и передает текст между скобками в объявлении пространства имен с условием в качестве параметра argument. Верните true, чтобы включить квалифицированную разметку, или false, чтобы игнорировать ее.
В этом примере из примера коллекции WinUI 3 оцениваются флаги функций, которые приложение хранит в словаре:
using System.Collections.Generic;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Markup;
namespace MyApp;
public sealed partial class FeatureFlagCondition : DependencyObject, IXamlCondition
{
public static IDictionary<string, bool> FeatureFlags { get; } = new Dictionary<string, bool>
{
["NewExperience"] = true,
["LegacyMode"] = false,
};
// The XAML parser calls Evaluate with the text between the parentheses
// in the conditional namespace declaration, for example "NewExperience".
public bool Evaluate(string argument)
{
return FeatureFlags.TryGetValue(argument, out bool enabled) && enabled;
}
}
Объявите условное пространство имен для условия
Сначала сопоставьте пространство имен, содержащее класс условия, с помощью объявления using:. Затем после ? разделителя условного пространства имен сошлитесь на класс через этот префикс и передайте аргумент в скобках:
xmlns:cond="using:MyApp"
xmlns:newExp="http://schemas.microsoft.com/winfx/2006/xaml/presentation?cond:FeatureFlagCondition(NewExperience)"
xmlns:legacy="http://schemas.microsoft.com/winfx/2006/xaml/presentation?cond:FeatureFlagCondition(LegacyMode)"
В этом примере средство синтаксического анализа вызывает Evaluate("NewExperience") для разметки, использующей префикс Evaluate("LegacyMode"), и legacy для разметки, использующей префикс newExp.
Использование условия для элементов, атрибутов и сеттеров
Используйте условный префикс так же, как и встроенные условные пространства имен. Эти примеры основаны на примере WinUI 3 Gallery.
Чтобы включить элемент только в том случае, если условие выполняется true, добавьте префикс к элементу:
<StackPanel Spacing="8">
<!-- Included only when FeatureFlagCondition.Evaluate("NewExperience") returns true. -->
<newExp:InfoBar Title="New experience" IsOpen="True" Severity="Success"
Message="This InfoBar is included because the NewExperience flag is true." />
<!-- Included only when FeatureFlagCondition.Evaluate("LegacyMode") returns true. -->
<legacy:InfoBar Title="Legacy mode" IsOpen="True" Severity="Warning"
Message="This InfoBar is included because the LegacyMode flag is true." />
</StackPanel>
Чтобы задать свойство только в том случае, если условие true, добавьте префикс к атрибуту:
<!-- Make sure that no more than one of these conditions is true at runtime. -->
<Button newExp:Content="Open the new editor"
legacy:Content="Open the classic editor" />
Чтобы применить сеттер стиля только в том случае, если условие равно true, добавьте префикс к элементу Setter:
<Page.Resources>
<Style x:Key="ConditionalHeadingStyle" TargetType="TextBlock">
<newExp:Setter Property="FontWeight" Value="SemiBold" />
<newExp:Setter Property="FontSize" Value="28" />
<legacy:Setter Property="FontWeight" Value="Normal" />
<legacy:Setter Property="FontSize" Value="18" />
</Style>
</Page.Resources>
Установите состояние перед анализом XAML
Средство синтаксического анализа кэширует результат Evaluate для каждого сочетания условия и аргумента на время существования процесса. Если изменить состояние, которое условие считывает после кэширования результата, разметка, которая уже обработана, не изменяется, и разметка, которая обрабатывается позже, использует кэшированный результат. Чтобы использовать другое значение, перезапустите приложение.
Задайте состояние, считываемое вашим условием перед тем, как парсер вычислит его, например при запуске приложения или перед вызовом InitializeComponent в конструкторе страницы:
public sealed partial class MainPage : Page
{
public MainPage()
{
// Set the flags before InitializeComponent so that the XAML parser
// uses these values when it evaluates the conditions.
FeatureFlagCondition.FeatureFlags["NewExperience"] = true;
FeatureFlagCondition.FeatureFlags["LegacyMode"] = false;
this.InitializeComponent();
}
}
Limitations
- Два элемента не могут иметь один и тот же
x:Name, даже если только один из них включен во время выполнения. - Если к одному атрибуту применяется несколько условий, убедитесь, что только одно из них вычисляется как
trueво время выполнения. Если более одного элемента вычисляется какtrue, средство синтаксического анализа вызывает исключение. - Так как условия оцениваются во время выполнения, компилятор XAML не может проверить их логическую согласованность. Проверьте каждое сочетание значений условий, которое поддерживает ваше приложение.
- Пользовательские условия не работают с элементами
x:из пространства имен (http://schemas.microsoft.com/winfx/2006/xaml), напримерx:Uidиx:Key.
Связанные материалы
Windows developer