Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Bedingter XAML-Code bietet eine Möglichkeit, die ApiInformation.IsApiContractPresent-Methode direkt im XAML-Markup zu verwenden. Sie können Eigenschaften basierend auf dem Vorhandensein eines API-Vertrags auf Betriebssystemlevel festlegen, ohne Backend-Code schreiben zu müssen. Bedingte Anweisungen werden zur Laufzeit ausgewertet – Elemente, die mit einem bedingten XAML-Tag qualifiziert sind, werden geparst, wenn sie den Wert true ergeben, andernfalls werden sie ignoriert.
Ab Windows App SDK 2.0 können Sie auch eigene Bedingungen definieren, indem Sie die IXamlCondition-Schnittstelle implementieren. Mit benutzerdefinierten Bedingungen können Sie Markup basierend auf appspezifischem Zustand, z. B. Featurekennzeichnungen oder Konfigurationseinstellungen, einschließen oder ausschließen. Weitere Informationen finden Sie unter Erstellen von benutzerdefinierten Bedingungen.
Bedingter XAML-Code erfordert Windows 10 Version 1809 (Build 17763) oder höher, was die Mindestversion des Betriebssystems für Windows App SDK-Apps ist.
Prerequisites
- Ein Windows App SDK Projekt. Schritte zum Einrichten finden Sie unter Erstellen und Ausführen eines WinUI 3-Projekts.
- Vertrautheit mit versionsadaptiven Apps und der
ApiInformation-Klasse.
Important
Die integrierten bedingten Methoden verwenden ApiInformation-Methoden, die überprüfen, ob Windows-Runtime (Windows.*) API-Kontrakte und -Typen vorhanden sind, die vom Betriebssystem bereitgestellt werden. Diese Prüfungen gelten nicht für WinUI 3 (Microsoft.UI.Xaml.*)-Steuerelemente, da WinUI 3 mit Ihrer App über das Windows App SDK statt mit dem Betriebssystem ausgeliefert wird – jedes WinUI 3-Steuerelement, für das Ihre App erstellt wird, ist zur Laufzeit immer vorhanden, unabhängig davon, für welche Windows 10/11-Build das Gerät ausgeführt wird.
#if Präprozessordirektiven helfen auch hier nicht weiter: Sie werden zum Kompilierungszeitpunkt anhand des Zielframeworks ausgewertet, nicht zur Laufzeit auf Grundlage des tatsächlich installierten Betriebssystems oder der tatsächlich installierten Version des Windows App SDK. Um die Verfügbarkeit einer Funktion von der Windows App SDK-Version abhängig zu machen, mit der Ihre App ausgeführt wird, überprüfen Sie die SDK-Version zur Buildzeit, oder schließen Sie den API-Aufruf in einen Try/Catch-Block ein. Weitere Informationen finden Sie unter Versionsadaptiver Code.
Hintergrundinformationen zu ApiInformation Und API-Verträgen finden Sie unter Versionsadaptive Apps.
Bedingte Namespaces
Um eine bedingte Methode in XAML zu verwenden, deklarieren Sie oben auf der Seite einen bedingten XAML-Namespace :
xmlns:myNamespace="schema?conditionalMethod(parameter)"
Der Inhalt vor dem ? Trennzeichen ist der Namespace oder das Schema. Der Inhalt nach ? ist die bedingte Methode, die bestimmt, ob der Namespace als true oder false ausgewertet wird.
In den meisten Fällen ist das Schema der standardmäßige XAML-Namespace:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Bedingter XAML-Code unterstützt diese bedingten Methoden:
| Methode | Invers |
|---|---|
IsApiContractPresent(ContractName, VersionNumber) |
IsApiContractNotPresent(ContractName, VersionNumber) |
IsTypePresent(ControlType) |
IsTypeNotPresent(ControlType) |
IsPropertyPresent(ControlType, PropertyName) |
IsPropertyNotPresent(ControlType, PropertyName) |
Sie können auch eine Bedingung verwenden, die Sie in Ihrer App definieren. Weitere Informationen finden Sie unter Erstellen von benutzerdefinierten Bedingungen.
Note
Verwenden Sie IsApiContractPresent und IsApiContractNotPresent für die beste Entwurfszeiterfahrung. Andere Bedingungen werden in der Entwurfsoberfläche Visual Studio nicht vollständig unterstützt.
Eine Eigenschaft bedingt festlegen
Dieses Beispiel zeigt Text in einem TextBlock nur dann an, wenn die App unter Windows 10 Version 1903 (Mai 2019 Update, Build 18362) oder höher ausgeführt wird – eine Vertragsprüfung, die sinnvoll ist, da sie neuer ist als die Mindestanforderung 1809 des Windows App SDK.
Definieren Sie zunächst einen bedingten Namespace:
xmlns:contract8Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,8)"
Stellen Sie dann der Eigenschaft den bedingten Namespace voran:
<TextBlock contract8Present:Text="Hello, Conditional XAML"/>
Hier ist das gesamte Markup:
<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>
Die entsprechende Überprüfung im Code-Behind:
TextBlock textBlock = new TextBlock();
if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
{
textBlock.Text = "Hello, Conditional XAML";
}
Note
IsApiContractPresent Obwohl eine Zeichenfolge für den Vertragsnamenparameter verwendet wird, fügen Sie sie nicht in Anführungszeichen in die XAML-Namespacedeklaration ein.
Da die vom Windows App SDK unterstützte Mindestversion des Betriebssystems 1809 (UniversalApiContract Version 7) ist, ergibt die Überprüfung auf eine Vertragsversion von 7 oder darunter in einer Windows App SDK-App stets den Wert true und liefert keine nützlichen Informationen. Überprüfen Sie nur auf Vertragsversionen, die höher als 7 sind.
Verwenden von If/Else-Bedingungen
Um je nach API-Vertrag unterschiedliche Werte festzulegen, definieren Sie sowohl die positiven als auch negativen bedingten Namespaces:
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)"
Legen Sie dann die Eigenschaft zweimal fest, jeweils mit einem anderen bedingten Präfix. Zur Laufzeit wird nur eins angewendet:
<TextBlock contract8NotPresent:Text="Hello, World"
contract8Present:Text="Hello, May 2019 Update or later"/>
Steuerelemente bedingt instanziieren
Note
Das bedingte Instanziieren eines Elements basierend auf einem Betriebssystem-API-Vertrag – im Gegensatz zum bedingten Festlegen einer Eigenschaft – ist ein UWP-spezifisches Muster. Sie gilt nicht für WinUI 3-Steuerelemente.
In UWP können Sie mit diesem Muster auf ein älteres Windows.UI.Xaml.Controls Steuerelement zurückgreifen, wenn ein neueres Steuerelement im Betriebssystem nicht verfügbar war. In einer Windows App SDK App werden WinUI 3-Steuerelemente (Microsoft.UI.Xaml.Controls.*) mit Ihrer App über die Windows App SDK ausgeliefert, nicht mit dem Betriebssystem. Jedes Steuerelement, mit dem Ihre App erstellt wird – einschließlich ColorPicker – ist garantiert zur Laufzeit vorhanden, sodass es keine Betriebssystemversion gibt, die überprüft werden kann, bevor sie instanziiert wird.
Wenn Sie ein WinUI 3-Steuerelement oder eine WinUI 3-API von der Version des Windows App SDK abhängig machen müssen, auf die Ihre App abzielt, führen Sie diese Prüfung zur Buildzeit durch (indem Sie eine Windows App SDK-Paketversion als Mindestversion festlegen) oder kapseln Sie den Laufzeitaufruf in try/catch – nicht mit bedingtem XAML.
Verwenden Sie eine benutzerdefinierte Bedingung, um Elemente basierend auf der Logik einzuschließen oder auszuschließen, die Ihre App definiert, z. B. ein Feature-Flag.
Benutzerdefinierte Bedingungen erstellen
Ab Windows App SDK 2.0 können Sie eigene Bedingungen definieren und mit der Syntax für bedingte Namespaces verwenden. Mit einer benutzerdefinierten Bedingung können Sie Markup basierend auf dem appspezifischen Zustand ein- oder ausschließen, z. B. auf Feature-Flags, Konfigurationseinstellungen oder Gerätefunktionen. Ähnlich wie bei den integrierten bedingten Methoden werden benutzerdefinierte Bedingungen ausgewertet, wenn der XAML-Code zur Laufzeit analysiert wird.
- Wichtige APIs: IXamlCondition-Schnittstelle, IXamlCondition.Evaluate-Methode
![]()
Die WinUI 3 Gallery-App enthält interaktive Beispiele für WinUI-Steuerelemente und -Features. Rufen Sie die App aus dem Microsoft Store ab, oder durchsuchen Sie den Quellcode auf GitHub.
Note
IXamlConditionersetzt die IXamlPredicate Schnittstelle aus experimentellen Versionen des Windows App SDK 2.0.
Eine Bedingung implementieren
Um eine Bedingung zu erstellen, definieren Sie eine Klasse, die von DependencyObject abgeleitet ist und IXamlCondition implementiert. Der XAML-Parser ruft die Evaluate-Methode auf und übergibt den Text zwischen den Klammern der bedingten Namespacedeklaration als argument-Parameter. Geben Sie true zurück, um das qualifizierte Markup einzuschließen oder false zu ignorieren.
In diesem Beispiel aus dem WinUI 3 Gallery sample werden Featureflags ausgewertet, die von der App in einem Wörterbuch gespeichert werden:
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;
}
}
Einen bedingten Namespace für die Bedingung deklarieren
Ordnen Sie zunächst den Namespace zu, der Ihre Bedingungsklasse enthält, mithilfe einer using: Deklaration. Verweisen Sie dann nach dem ? Trennzeichen eines bedingten Namespaces über dieses Präfix auf die Klasse, und übergeben Sie das Argument in Klammern:
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)"
In diesem Beispiel ruft der Parser Evaluate("NewExperience") für Markup auf, das das newExp-Präfix verwendet, und Evaluate("LegacyMode") für Markup, das das legacy-Präfix verwendet, auf.
Verwenden Sie die Bedingung für Elemente, Attribute und Setter
Verwenden Sie das bedingte Präfix auf die gleiche Weise wie die integrierten bedingten Namespaces. Diese Beispiele basieren auf dem WinUI 3 Gallery-Beispiel.
Um ein Element nur einzuschließen, wenn eine Bedingung true ist, präfixieren Sie das Element:
<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>
Wenn Sie eine Eigenschaft nur festlegen möchten, wenn eine Bedingung true ist, stellen Sie dem Attribut das Präfix voran:
<!-- 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" />
Wenn Sie einen Formatvorlagensetter nur anwenden möchten, wenn eine Bedingung lautet true, stellen Sie dem Element Setter ein Präfix voran:
<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>
Legen Sie den Zustand fest, bevor der XAML-Code analysiert wird
Der Parser zwischenspeichert das Ergebnis von Evaluate für jede Kombination von Bedingung und Argument während der Lebensdauer des Prozesses. Wenn Sie den Zustand ändern, den eine Bedingung liest, nachdem das Ergebnis zwischengespeichert wurde, ändert sich das bereits analysierte Markup nicht, und das zu einem späteren Zeitpunkt analysierte Markup verwendet weiterhin das zwischengespeicherte Ergebnis. Um einen anderen Wert zu verwenden, starten Sie die App neu.
Legen Sie den Zustand fest, den die Bedingung liest, bevor der Parser sie auswertet, z. B. beim Starten der App oder bevor Sie InitializeComponent in einem Seitenkonstruktor aufrufen:
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
- Zwei Elemente können nicht dieselbe
x:Namehaben, auch wenn nur eine davon zur Laufzeit enthalten ist. - Wenn Sie mehrere Bedingungen auf dasselbe Attribut anwenden, stellen Sie sicher, dass zur Laufzeit nur eine von ihnen zu
trueausgewertet wird. Wenn mehr als einer zutrueausgewertet wird, löst der Parser eine Ausnahme aus. - Da Bedingungen zur Laufzeit ausgewertet werden, kann der XAML-Compiler sie nicht auf logische Konsistenz überprüfen. Testen Sie jede Kombination von Bedingungswerten, die Ihre App unterstützt.
- Benutzerdefinierte Bedingungen funktionieren nicht mit Elementen aus dem
x:-Namespace (http://schemas.microsoft.com/winfx/2006/xaml), z. B.x:Uidundx:Key.
Verwandte Inhalte
Windows developer