Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
XAML condizionale consente di usare il metodo ApiInformation.IsApiContractPresent direttamente nel markup XAML. È possibile impostare le proprietà in base alla presenza di un contratto API a livello di sistema operativo senza scrivere code-behind. Le istruzioni condizionali vengono valutate in fase di esecuzione: gli elementi qualificati con un tag XAML condizionale vengono analizzati se restituiscono true e ignorati in caso contrario.
A partire da SDK per app di Windows 2.0, è anche possibile definire le proprie condizioni implementando l'interfaccia IXamlCondition. Le condizioni personalizzate consentono di includere o escludere markup in base allo stato specifico dell'app, ad esempio flag di funzionalità o impostazioni di configurazione. Per altre info, vedi Creare condizioni personalizzate.
XAML condizionale richiede Windows 10 versione 1809 (build 17763) o successiva, ovvero la versione minima del sistema operativo per le app SDK per app di Windows.
Prerequisiti
- Progetto di SDK per app di Windows. Per i passaggi di installazione, vedere Creare ed eseguire un progetto WinUI 3.
- Familiarità con le app con versione adattiva e la classe
ApiInformation.
Importante
I metodi condizionali integrati usano metodi ApiInformation, che controllano la presenza di contratti API e tipi Windows Runtime (Windows.*) forniti dal sistema operativo. Questi controlli non si applicano ai controlli WinUI 3 (Microsoft.UI.Xaml.*), perché WinUI 3 viene fornito con l'app tramite il SDK per app di Windows anziché con il sistema operativo. Ogni controllo WinUI 3 su cui viene compilata l'app è sempre presente in fase di esecuzione, indipendentemente dal Windows 10/11 in cui è in esecuzione il dispositivo.
#ifLe direttive del preprocessore non sono utili in questo caso: vengono valutate in fase di compilazione in base al framework di destinazione, non in fase di esecuzione in base al sistema operativo o alla versione SDK per app di Windows effettivamente installata. Per subordinare una funzionalità alla versione di SDK per app di Windows con cui l'app è in esecuzione, verificare la versione dell'SDK in fase di compilazione oppure racchiudere la chiamata API in un blocco try/catch. Per informazioni dettagliate, vedere Codice adattivo della versione .
Per informazioni di base su ApiInformation e i contratti API, vedere App adattive alla versione.
Namespace condizionali
Per usare un metodo condizionale in XAML, dichiarare uno spazio dei nomi XAML condizionale nella parte superiore della pagina:
xmlns:myNamespace="schema?conditionalMethod(parameter)"
Il contenuto prima del ? delimitatore è lo spazio dei nomi o lo schema. Il contenuto dopo ? è il metodo condizionale che determina se lo spazio dei nomi restituisce true o false.
Nella maggior parte dei casi, lo schema è lo spazio dei nomi XAML predefinito:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
XAML condizionale supporta questi metodi condizionali:
| Method | Inverso |
|---|---|
IsApiContractPresent(ContractName, VersionNumber) |
IsApiContractNotPresent(ContractName, VersionNumber) |
IsTypePresent(ControlType) |
IsTypeNotPresent(ControlType) |
IsPropertyPresent(ControlType, PropertyName) |
IsPropertyNotPresent(ControlType, PropertyName) |
È anche possibile usare una condizione definita nell'app. Per altre info, vedi Creazione di condizioni personalizzate.
Note
Usare IsApiContractPresent e IsApiContractNotPresent per un'esperienza ottimale in fase di progettazione. Altre condizionali non sono completamente supportate nell'esperienza di progettazione Visual Studio.
Impostare una proprietà in modo condizionale
Questo esempio visualizza il testo in un TextBlock solo quando l'app viene eseguita su Windows 10 versione 1903 (Aggiornamento di maggio 2019, build 18362) o versioni successive, ovvero una verifica del contratto che ha senso perché è più recente della versione minima 1809 di SDK per app di Windows.
Prima di tutto, definire uno spazio dei nomi condizionale:
xmlns:contract8Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,8)"
Quindi anteporre alla proprietà lo spazio dei nomi condizionale:
<TextBlock contract8Present:Text="Hello, Conditional XAML"/>
Ecco il markup completo:
<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>
Il controllo equivalente nel code-behind:
TextBlock textBlock = new TextBlock();
if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
{
textBlock.Text = "Hello, Conditional XAML";
}
Note
Anche se IsApiContractPresent accetta una stringa per il parametro nome contratto, non viene inserita tra virgolette nella dichiarazione dello spazio dei nomi XAML.
Poiché la versione minima del sistema operativo supportata da SDK per app di Windows è 1809 (UniversalApiContract versione 7), verificare una versione di contratto uguale o inferiore a 7 restituisce sempre true in un'app SDK per app di Windows e non fornisce alcuna informazione utile. Controllare solo le versioni del contratto superiori a 7.
Usare condizioni if/else
Per impostare valori diversi a seconda del contratto dell'API, definire sia i namespace condizionali positivi sia quelli negativi:
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)"
Impostare quindi la proprietà due volte, ognuna con un prefisso condizionale diverso. Solo uno viene applicato in fase di esecuzione:
<TextBlock contract8NotPresent:Text="Hello, World"
contract8Present:Text="Hello, May 2019 Update or later"/>
Istanziare i controlli condizionalmente
Note
Creare un'istanza condizionale di un elemento basato su un contratto API del sistema operativo, anziché impostare in modo condizionale una proprietà , è un modello specifico della piattaforma UWP. Non si applica ai controlli WinUI 3.
In UWP questo modello ti consente di eseguire il fallback a un controllo precedente Windows.UI.Xaml.Controls quando un controllo più recente non era disponibile nel sistema operativo. In un'app SDK per app di Windows, i controlli WinUI 3 (Microsoft.UI.Xaml.Controls.*) vengono forniti con l'app tramite il SDK per app di Windows, non con il sistema operativo. Ogni controllo su cui è basata l'app, incluso ColorPicker, sarà sicuramente presente in fase di esecuzione, quindi non è necessario controllare la versione del sistema operativo prima di istanziarlo.
Se devi subordinare un controllo o un'API WinUI 3 alla versione di SDK per app di Windows a cui è destinata l'app, effettua questa verifica in fase di compilazione (impostando come destinazione una versione minima del pacchetto SDK per app di Windows) oppure racchiudi la chiamata di runtime in un try/catch — non usando XAML condizionale.
Per includere o escludere elementi in base alla logica definita dall'app, ad esempio un flag di funzionalità, usare una condizione personalizzata.
Creare condizioni personalizzate
A partire da SDK per app di Windows 2.0, è possibile definire le proprie condizioni e usarle con la sintassi dello spazio dei nomi condizionale. Una condizione personalizzata consente di includere o escludere markup in base allo stato specifico dell'app, ad esempio flag di funzionalità, impostazioni di configurazione o funzionalità del dispositivo. Analogamente ai metodi condizionali predefiniti, le condizioni personalizzate vengono valutate quando xaml viene analizzato in fase di esecuzione.
- API importanti: interfaccia IXamlCondition, metodo IXamlCondition.Evaluate
![]()
L'app Raccolta WinUI 3 include esempi interattivi di controlli e funzionalità WinUI. Ottenere l'app dal Microsoft Store o esplorare il codice sorgente in GitHub.
Note
IXamlCondition sostituisce l'interfaccia IXamlPredicate nelle versioni sperimentali di SDK per app di Windows 2.0.
Definire una condizione
Per creare una condizione, definire una classe che deriva da DependencyObject e implementa IXamlCondition. Il parser XAML chiama il metodo Evaluate e passa il testo tra le parentesi della dichiarazione dello spazio dei nomi condizionale come argument parametro. Seleziona true per includere il markup completo o false per ignorarlo.
Questo esempio, tratto dal sample WinUI 3 Gallery, valuta i flag di funzionalità che l'app archivia in un dizionario:
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;
}
}
Dichiarare uno spazio dei nomi condizionale per la condizione
Prima di tutto, mappate lo spazio dei nomi contenente la classe di condizione usando una dichiarazione using:. Quindi, dopo il ? delimitatore di uno spazio dei nomi condizionale, fare riferimento alla classe tramite tale prefisso e passare l'argomento tra parentesi:
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 questo esempio, il parser chiama Evaluate("NewExperience") per il markup che usa il newExp prefisso e Evaluate("LegacyMode") per il markup che usa il legacy prefisso.
Usare la condizione su elementi, attributi e setter
Usare il prefisso condizionale nello stesso modo in cui si usano gli spazi dei nomi condizionali predefiniti. Questi esempi sono basati sull'esempio WinUI 3 Gallery.
Per includere un elemento solo quando una condizione è true, anteporre l'elemento:
<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>
Per impostare una proprietà solo se una condizione è true, anteporre l'attributo:
<!-- 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" />
Per applicare un setter di stile solo quando una condizione è true, anteporre l'elemento 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>
Impostare lo stato prima dell'analisi di XAML
Il parser memorizza nella cache il risultato di Evaluate per ogni combinazione di condizione e argomento per la durata del processo. Se si modifica lo stato letto da una condizione dopo la memorizzazione nella cache del risultato, il markup già analizzato non cambia e il markup analizzato in un secondo momento usa comunque il risultato memorizzato nella cache. Per usare un valore diverso, riavviare l'app.
Impostare lo stato letto dalla condizione prima che il parser lo valuta, ad esempio all'avvio dell'app o prima di chiamare InitializeComponent in un costruttore di pagina:
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
- Due elementi non possono avere lo stesso
x:Name, anche se solo uno di essi è incluso in fase di esecuzione. - Se si applicano più condizioni allo stesso attributo, assicurarsi che solo una di esse restituisca
truein fase di esecuzione. Se più di uno restituiscetrue, il parser genera un'eccezione. - Poiché le condizioni vengono valutate in fase di esecuzione, il compilatore XAML non può controllarle per verificare la coerenza logica. Testa ogni combinazione di valori delle condizioni che la tua app supporta.
- Le condizioni personalizzate non funzionano con gli elementi del namespace
x:(http://schemas.microsoft.com/winfx/2006/xaml), ad esempiox:Uidex:Key.