Feltételes XAML

A feltételes XAML lehetővé teszi az ApiInformation.IsApiContractPresent metódus közvetlen használatát az XAML-korrektúrában. A tulajdonságokat egy operációsrendszer-szintű API-szerződés jelenléte alapján állíthatja be anélkül, hogy kódokat ír le. A feltételes utasítások futásidőben értékelődnek ki – a feltételes XAML-címkével ellátott elemeket a rendszer feldolgozza, ha true értékre értékelődnek ki, ellenkező esetben pedig figyelmen kívül hagyja őket.

A 2.0-s Windows App SDK-tól kezdve saját feltételeket is meghatározhat az IXamlCondition interfész implementálásával. Az egyéni feltételek lehetővé teszik a jelölés belefoglalását vagy kizárását alkalmazásspecifikus állapot, például funkciójelzők vagy konfigurációs beállítások alapján. További információ: Egyéni feltételek létrehozása.

A feltételes XAML-hez Windows 10 1809-es (17763-as build) vagy újabb verzió szükséges, amely Windows App SDK alkalmazások minimális operációsrendszer-verziója.

Prerequisites

Important

A beépített feltételes metódusok ApiInformation metódusokat használnak, amelyek ellenőrzik az operációs rendszer által biztosított Windows-futtatókörnyezet (Windows.*) API-szerződéseknek és -típusoknak a meglétét. Ezek az ellenőrzések nem vonatkoznak a WinUI 3 (Microsoft.UI.Xaml.*) vezérlőkre, mivel a WinUI 3 nem az operációs rendszerrel, hanem az Windows App SDK szállítja az alkalmazást – az alkalmazás minden WinUI 3 vezérlője futásidőben mindig jelen van, függetlenül attól, hogy melyik Windows 10/11 builden fut az eszköz. #ifaz előprocesszor-irányelvek itt sem segítenek: fordításkor lesznek kiértékelve a cél keretrendszer alapján, nem futtatókörnyezetben az operációs rendszer vagy a ténylegesen telepített Windows App SDK verzió alapján. Ha egy funkció elérhetőségét attól szeretné függővé tenni, hogy az alkalmazás a Windows App SDK melyik verziójával fut, ellenőrizze az SDK verzióját fordításkor, vagy helyezze az API-hívást try/catch blokkba. Részletekért lásd a verzió adaptív kódját .

A háttérinformációkról és az API-szerződésekről ApiInformation lásd: Adaptív verziójú alkalmazások.

Feltételes névterek

Ha feltételes módszert szeretne használni az XAML-ben, deklaráljon egy feltételes XAML-névteret a lap tetején:

xmlns:myNamespace="schema?conditionalMethod(parameter)"

A határoló előtt lévő ? tartalom a névtér vagy séma. A ? utáni tartalom az a feltételes metódus, amely meghatározza, hogy a névtér true vagy false értékre értékelődik ki.

A legtöbb esetben a séma az alapértelmezett XAML-névtér:

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

A feltételes XAML a következő feltételes módszereket támogatja:

Módszer Inverz
IsApiContractPresent(ContractName, VersionNumber) IsApiContractNotPresent(ContractName, VersionNumber)
IsTypePresent(ControlType) IsTypeNotPresent(ControlType)
IsPropertyPresent(ControlType, PropertyName) IsPropertyNotPresent(ControlType, PropertyName)

Az alkalmazásban definiált feltételt is használhatja. További információ: Egyéni feltételek létrehozása.

Note

A legjobb tervezési idejű használhatóság érdekében használja a(z) IsApiContractPresent és IsApiContractNotPresent elemeket. Az egyéb feltételes feltételek nem támogatottak teljes mértékben a Visual Studio tervezési felületen.

Tulajdonság feltételes beállítása

Ez a példa csak akkor jeleníti meg a szövegetTextBlock, ha az alkalmazás Windows 10 1903-ban (2019. májusi frissítés, 18362-es build) vagy újabb verzióban fut – ez a szerződés-ellenőrzés azért fontos, mert az újabb, mint a Windows App SDK 1809-es emelete.

Először definiáljon egy feltételes névteret:

xmlns:contract8Present="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,8)"

Ezután lássa el a tulajdonságot a feltételes névtér előtagjával:

<TextBlock contract8Present:Text="Hello, Conditional XAML"/>

Íme a teljes jelölőkód:

<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>

Az ezzel egyenértékű bejelentkezési kód a háttérben:

TextBlock textBlock = new TextBlock();

if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
{
    textBlock.Text = "Hello, Conditional XAML";
}

Note

Bár a(z) IsApiContractPresent a szerződésnév paramétereként karakterláncot fogad el, az XAML-névtér deklarációjában nem kell idézőjelek közé tenni.

Mivel a Windows App SDK minimálisan támogatott operációsrendszer-verziója 1809 (UniversalApiContract7-es verzió), a szerződés 7-es vagy újabb verziójának ellenőrzése mindig egy Windows App SDK-alkalmazásban történiktrue, és nem nyújt hasznos információt. Csak a 7-nél nagyobb szerződésverziókat ellenőrizze.

If/else feltételek használata

Ha az API-szerződéstől függően különböző értékeket szeretne beállítani, adja meg a pozitív és a negatív feltételes névtereket is:

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)"

Ezután állítsa be kétszer a tulajdonságot, mindegyikhez egy másik feltételes előtag tartozik. Futtatókörnyezetben csak egy van alkalmazva:

<TextBlock contract8NotPresent:Text="Hello, World"
           contract8Present:Text="Hello, May 2019 Update or later"/>

Vezérlők feltételes példányosítása

Note

Az operációsrendszer-API-szerződésen alapuló elem feltételes példányosítása – szemben a tulajdonság feltételes beállításával – UWP-specifikus minta. Ez nem vonatkozik a WinUI 3 vezérlőkre.

Az UWP-ben ez a minta lehetővé teszi, hogy visszatérjen egy régebbi Windows.UI.Xaml.Controls vezérlőhöz, amikor egy újabb nem volt elérhető az operációs rendszeren. Egy Windows App SDK-alkalmazásban a WinUI 3-vezérlők (Microsoft.UI.Xaml.Controls.*) az alkalmazás részeként, a Windows App SDK-n keresztül érkeznek, nem pedig az operációs rendszer részeként. Minden vezérlő, amelyre az alkalmazás épül — beleértve a(z) ColorPicker elemet is — garantáltan elérhető lesz futásidőben, így a példányosítása előtt nem kell ellenőrizni az operációs rendszer verzióját.

Ha egy WinUI 3-vezérlő vagy API használatát az alkalmazás által célzott Windows App SDK-verzióhoz kell kötni, ezt buildidőben tegye meg (a Windows App SDK-csomag minimális verziójának megadásával), vagy csomagolja a futásidejű hívást try/catch közé – ne feltételes XAML-lel.

Ha az alkalmazás által definiált logika alapján szeretne elemeket belefoglalni vagy kizárni, például egy funkciójelölő segítségével, használjon egyéni feltételt.

Egyéni feltételek létrehozása

A Windows App SDK 2.0-tól kezdve saját feltételeket határozhat meg, és használhatja őket a feltételes névtér szintaxisával. Az egyéni feltételek lehetővé teszik az alkalmazásspecifikus állapoton alapuló jelölőelemek beillesztését vagy kizárását, például a funkciójelzők, a konfigurációs beállítások vagy az eszközképességek alapján. A beépített feltételes metódusokhoz hasonlóan az egyéni feltételeket is kiértékeli a rendszer, amikor az XAML elemzése futásidőben történik.

WinUI 3 Katalógus ikon A WinUI 3 Katalógus alkalmazás interaktív példákat tartalmaz a WinUI vezérlőire és funkcióira. Kérje le az alkalmazást a Microsoft Áruházból vagy keresse meg a forráskódot a GitHub webhelyen.

Note

IXamlCondition felváltja a IXamlPredicate interfészt a Windows App SDK 2.0 kísérleti kiadásaiból.

Feltétel létrehozása

Feltétel létrehozásához definiáljon egy, a DependencyObjectből származó és IXamlCondition implementáló osztályt. Az XAML-elemző meghívja a Evaluate metódust, és paraméterként argument átadja a szöveget a feltételes névtér-deklaráció zárójelei között. Adja vissza a(z) true értéket a minősített jelölés belefoglalásához, vagy a(z) false értéket a figyelmen kívül hagyásához.

Ez a példa a WinUI 3 Katalógus mintájából kiértékeli az alkalmazás által egy szótárban tárolt funkciójelzőket:

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;
    }
}

Feltételes névtér deklarálása a feltételhez

Először képezze le a feltétel osztályát tartalmazó névteret egy using: deklarációval. Ezután a ? feltételes névtér elválasztójele után hivatkozzon az osztályra az előtag használatával, és adja át az argumentumot zárójelben:

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)"

Ebben a példában a parser a newExp előtagot használó jelölésekhez a Evaluate("LegacyMode") elemet, a legacy előtagot használó jelölésekhez pedig a Evaluate("NewExperience") elemet hívja meg.

A feltétel használata elemeken, attribútumokon és settereken

A feltételes előtagot ugyanúgy használja, mint a beépített feltételes névtereket. Ezek a példák a WinUI 3 katalógusmintán alapulnak.

Ha egy elemet csak akkor szeretne belefoglalni, ha egy feltétel teljesül true, lássa el az elemet előtaggal:

<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>

Ha csak feltétel esetén true szeretne tulajdonságot beállítani, írja az attribútum elé:

<!-- 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" />

Ha csak feltétel true esetén szeretne stílusválasztót alkalmazni, akkor tegye a(z) Setter elemet előtagként:

<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>

Állítsa be az állapotot az XAML elemzése előtt

Az elemző gyorsítótárazza a(z) Evaluate eredményét minden feltétel- és argumentumkombinációhoz a folyamat élettartama alatt. Ha módosítja azt az állapotot, amelyet egy feltétel olvas az eredmény gyorsítótárazása után, a már elemzett jelölés nem változik, és a később elemzett jelölés továbbra is a gyorsítótárazott eredményt használja. Másik érték használatához indítsa újra az alkalmazást.

Állítsa be azt az állapotot, amelyet a feltétel kiolvas, mielőtt az elemző kiértékeli azt, például az alkalmazás indításakor vagy mielőtt meghívná a(z) InitializeComponent elemet egy lap konstruktorában:

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

  • Két elem nem rendelkezhet ugyanazzal a(z) x:Name-val, még akkor sem, ha futásidőben csak az egyik van belefoglalva.
  • Ha egynél több feltételt alkalmaz ugyanarra az attribútumra, győződjön meg arról, hogy futásidőben csak az egyik értékelődik ki true-ra. Ha egynél több értéke true, az elemző kivételt jelez.
  • Mivel a feltételek kiértékelése futásidőben történik, az XAML-fordító nem tudja logikai konzisztencia szempontjából ellenőrizni őket. Tesztelje az alkalmazás által támogatott feltételértékek minden kombinációját.
  • Az egyéni feltételek nem használhatók a x: névtér (http://schemas.microsoft.com/winfx/2006/xaml) elemeivel, például x:Uid és x:Key.