Utilizzare estensioni di markup XAML

Browse sample. Esplorare l'esempio

Le estensioni di markup XAML dell'interfaccia utente di app multipiattaforma .NET (.NET MAUI) consentono di migliorare la potenza e la flessibilità di XAML consentendo l'impostazione degli attributi degli elementi da un'ampia gamma di origini.

Ad esempio, si imposta in genere la Color proprietà di BoxView come segue:

<BoxView Color="Blue" />

Tuttavia, è preferibile impostare l'attributo Color da un valore archiviato in un dizionario risorse o dal valore di una proprietà statica di una classe creata o da una proprietà di tipo Color di un altro elemento nella pagina oppure costruito da valori di tonalità, saturazione e luminosità separati. Tutte queste opzioni sono possibili usando le estensioni di markup XAML.

Un'estensione di markup è un modo diverso per esprimere un attributo di un elemento. Le estensioni di markup XAML .NET MAUI sono in genere identificabili da un valore di attributo racchiuso tra parentesi graffe:

<BoxView Color="{StaticResource themeColor}" />

Qualsiasi valore dell'attributo tra parentesi graffe è sempre un'estensione di markup XAML. Tuttavia, è anche possibile fare riferimento alle estensioni di markup XAML senza l'uso di parentesi graffe.

Nota

Diverse estensioni di markup XAML fanno parte della specifica XAML 2009. Questi vengono visualizzati nei file XAML con il prefisso dello spazio dei nomi personalizzato x e vengono comunemente indicati con questo prefisso.

Oltre alle estensioni di markup descritte in questo articolo, le estensioni di markup seguenti sono incluse in .NET MAUI e descritte in altri articoli:

Estensione di markup x:Static

L'estensione x:Static di markup è supportata dalla StaticExtension classe . La classe ha una singola proprietà denominata Member di tipo string impostata sul nome di una costante pubblica, di una proprietà statica, di un campo statico o di un membro di enumerazione.

Un modo per usare x:Static consiste nel definire prima una classe con alcune costanti o variabili statiche, ad esempio questa AppConstants classe:

static class AppConstants
{
    public static double NormalFontSize = 18;
}

Il codice XAML seguente illustra l'approccio più dettagliato per creare un'istanza della StaticExtension classe tra Label.FontSize tag di elemento proprietà:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:sys="clr-namespace:System;assembly=netstandard"
             xmlns:local="clr-namespace:MarkupExtensions"
             x:Class="MarkupExtensions.StaticDemoPage"
             Title="x:Static Demo">
    <StackLayout Margin="10, 0">
        <Label Text="Label No. 1">
            <Label.FontSize>
                <x:StaticExtension Member="local:AppConstants.NormalFontSize" />
            </Label.FontSize>
        </Label>
        ···
    </StackLayout>
</ContentPage>

Il parser XAML consente anche di abbreviatare la StaticExtension classe come x:Static:

<Label Text="Label No. 2">
    <Label.FontSize>
        <x:Static Member="local:AppConstants.NormalFontSize" />
    </Label.FontSize>
</Label>

Questa sintassi può essere ulteriormente semplificata inserendo la classe e l'impostazione StaticExtension del membro tra parentesi graffe. L'espressione risultante viene impostata direttamente sull'attributo FontSize :

<Label Text="Label No. 3"
       FontSize="{x:StaticExtension Member=local:AppConstants.NormalFontSize}" />

In questo esempio non vi sono virgolette tra parentesi graffe. La Member proprietà di StaticExtension non è più un attributo XML. È invece parte dell'espressione per l'estensione di markup.

Proprio come è possibile abbreviato x:StaticExtension in x:Static quando lo si usa come elemento oggetto, è anche possibile abbreviarlo nell'espressione all'interno di parentesi graffe:

<Label Text="Label No. 4"
       FontSize="{x:Static Member=local:AppConstants.NormalFontSize}" />

La StaticExtension classe ha un ContentProperty attributo che fa riferimento alla proprietà Member, che contrassegna questa proprietà come proprietà di contenuto predefinita della classe. Per le estensioni di markup XAML espresse con parentesi graffe, puoi eliminare la Member= parte dell'espressione:

<Label Text="Label No. 5"
       FontSize="{x:Static local:AppConstants.NormalFontSize}" />

Si tratta della forma più comune dell'estensione x:Static di markup.

Il tag radice dell'esempio XAML contiene anche una dichiarazione dello spazio dei nomi XML per lo spazio dei nomi .NET System . In questo modo le dimensioni del Label carattere possono essere impostate sul campo Math.PIstatico . Ciò comporta un testo piuttosto piccolo, quindi la Scale proprietà è impostata su Math.E:

<Label Text="&#x03C0; &#x00D7; E sized text"
       FontSize="{x:Static sys:Math.PI}"
       Scale="{x:Static sys:Math.E}"
       HorizontalOptions="Center" />

Lo screenshot seguente mostra l'output XAML:

x:Static demo.

Estensione di markup x:Reference

L'estensione x:Reference di markup è supportata dalla ReferenceExtension classe . La classe ha una singola proprietà denominata Name di tipo string impostata sul nome di un elemento nella pagina a cui è stato assegnato un nome con x:Name. Questa Name proprietà è la proprietà del contenuto di ReferenceExtension, pertanto Name= non è necessaria quando x:Reference viene visualizzata tra parentesi graffe. L'estensione x:Reference di markup viene usata esclusivamente con i data binding. Per altre informazioni sui data binding, vedere Data binding.

L'esempio XAML seguente mostra due usi di x:Reference con data binding, il primo in cui viene usato per impostare la Source proprietà dell'oggetto Binding e il secondo in cui viene usata per impostare la BindingContext proprietà per due data binding:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MarkupExtensions.ReferenceDemoPage"
             x:Name="page"
             Title="x:Reference Demo">    
    <StackLayout Margin="10, 0">        
        <Label Text="{Binding Source={x:Reference page},
                              StringFormat='The type of this page is {0}'}"
               FontSize="18"
               VerticalOptions="Center"
               HorizontalTextAlignment="Center" />
        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="Center" />
        <Label BindingContext="{x:Reference slider}"
               Text="{Binding Value, StringFormat='{0:F0}&#x00B0; rotation'}"
               Rotation="{Binding Value}"
               FontSize="24"
               HorizontalOptions="Center"
               VerticalOptions="Center" />        
    </StackLayout>
</ContentPage>

In questo esempio entrambe x:Reference le espressioni usano la versione abbreviata del nome della ReferenceExtension classe ed eliminano la Name= parte dell'espressione. Nel primo esempio l'estensione x:Reference di markup è incorporata nell'estensione Binding di markup e le Source proprietà e StringFormat sono separate da virgole.

Lo screenshot seguente mostra l'output XAML:

x:Reference demo.

Estensione di markup x:Type

L'estensione x:Type di markup è l'equivalente XAML della parola chiave C# typeof . È supportato dalla TypeExtension classe , che definisce una proprietà denominata TypeName di tipo string che deve essere impostata su un nome di classe o struttura. L'estensione x:Type di markup restituisce l'oggetto Type della classe o della struttura. TypeName è la proprietà del contenuto di TypeExtension, pertanto TypeName= non è necessario quando x:Type viene visualizzato con parentesi graffe.

L'estensione x:Type di markup viene comunemente usata con l'estensione di x:Array markup. Per altre informazioni, vedere estensione di markup x:Array.

L'esempio XAML seguente illustra l'uso dell'estensione di markup per creare un'istanza x:Type di oggetti MAUI .NET e aggiungerli a un oggetto StackLayout. Il codice XAML è costituito da tre Button elementi con le relative Command proprietà impostate su e Binding le CommandParameter proprietà impostate su tipi di tre visualizzazioni MAUI .NET:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MarkupExtensions.TypeDemoPage"
             Title="x:Type Demo">    
    <StackLayout x:Name="stackLayout"
                 Padding="10, 0">        
        <Button Text="Create a Slider"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                Command="{Binding CreateCommand}"
                CommandParameter="{x:Type Slider}" />
        <Button Text="Create a Stepper"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                Command="{Binding CreateCommand}"
                CommandParameter="{x:Type Stepper}" />
        <Button Text="Create a Switch"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                Command="{Binding CreateCommand}"
                CommandParameter="{x:Type Switch}" />
    </StackLayout>
</ContentPage>

Il file code-behind definisce e inizializza la CreateCommand proprietà :

public partial class TypeDemoPage : ContentPage
{
    public ICommand CreateCommand { get; private set; }

    public TypeDemoPage()
    {
        InitializeComponent();

        CreateCommand = new Command<Type>((Type viewType) =>
        {
            View view = (View)Activator.CreateInstance(viewType);
            view.VerticalOptions = LayoutOptions.Center;
            stackLayout.Add(view);
        });

        BindingContext = this;
    }
}

Quando viene premuto un oggetto Button viene creata una nuova istanza dell'argomento CommandParameter e aggiunta a StackLayout. I tre Button oggetti condividono quindi la pagina con visualizzazioni create dinamicamente:

x:Type demo.

Estensione di markup x:Array

L'estensione x:Array di markup consente di definire una matrice nel markup. È supportato dalla ArrayExtension classe , che definisce due proprietà:

  • Type di tipo Type, che indica il tipo degli elementi nella matrice. Questa proprietà deve essere impostata su un'estensione x:Type di markup.
  • Items di tipo IList, che è una raccolta degli elementi stessi. Si tratta della proprietà del contenuto di ArrayExtension.

L'estensione x:Array di markup stessa non viene mai visualizzata tra parentesi graffe. I tag iniziale e finale delimitano invece x:Array l'elenco di elementi.

L'esempio XAML seguente illustra come usare x:Array per aggiungere elementi a un ListView oggetto impostando la ItemsSource proprietà su una matrice:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MarkupExtensions.ArrayDemoPage"
             Title="x:Array Demo Page">
    <ListView Margin="10">
        <ListView.ItemsSource>
            <x:Array Type="{x:Type Color}">
                <Color>Aqua</Color>
                <Color>Black</Color>
                <Color>Blue</Color>
                <Color>Fuchsia</Color>
                <Color>Gray</Color>
                <Color>Green</Color>
                <Color>Lime</Color>
                <Color>Maroon</Color>
                <Color>Navy</Color>
                <Color>Olive</Color>
                <Color>Pink</Color>
                <Color>Purple</Color>
                <Color>Red</Color>
                <Color>Silver</Color>
                <Color>Teal</Color>
                <Color>White</Color>
                <Color>Yellow</Color>
            </x:Array>
        </ListView.ItemsSource>
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <BoxView Color="{Binding}"
                             Margin="3" />
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>     

In questo esempio, crea ViewCell una voce di colore semplice BoxView per ogni voce di colore:

x:Array demo.

Nota

Quando si definiscono matrici di tipi comuni come stringhe o numeri, usare i tag delle primitive del linguaggio XAML elencati in Argomenti pass.

Estensione di markup x:Null

L'estensione x:Null di markup è supportata dalla NullExtension classe . Non ha proprietà ed è semplicemente l'equivalente XAML della parola chiave C# null .

L'esempio XAML seguente illustra come usare l'estensione di x:Null markup:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MarkupExtensions.NullDemoPage"
             Title="x:Null Demo">
    <ContentPage.Resources>
        <Style TargetType="Label">
            <Setter Property="FontSize" Value="48" />
            <Setter Property="FontFamily" Value="OpenSansRegular" />
        </Style>
    </ContentPage.Resources>

    <StackLayout Padding="10, 0">
        <Label Text="Text 1" />
        <Label Text="Text 2" />
        <Label Text="Text 3"
               FontFamily="{x:Null}" />
        <Label Text="Text 4" />
        <Label Text="Text 5" />
    </StackLayout>
</ContentPage>      

In questo esempio viene definito un oggetto implicito Style per Label che include un Setter oggetto che imposta la FontFamily proprietà su un tipo di carattere specifico. Tuttavia, il terzo Label evita di usare il tipo di carattere definito nello stile implicito impostandone FontFamily su x:Null:

x:Null demo.

Estensione di markup DataTemplate

L'estensione DataTemplate di markup consente di convertire un tipo in un oggetto DataTemplate. È supportato dalla DataTemplateExtension classe , che definisce una TypeName proprietà di tipo string, impostata sul nome del tipo da convertire in .DataTemplate La TypeName proprietà è la proprietà content di DataTemplateExtension. Pertanto, per le espressioni di markup XAML espresse con parentesi graffe, è possibile eliminare la TypeName= parte dell'espressione.

Nota

Il parser XAML consente di abbreviatare la DataTemplateExtension classe come DataTemplate.

Un utilizzo tipico di questa estensione di markup si trova in un'applicazione Shell, come illustrato nell'esempio seguente:

<ShellContent Title="Monkeys"
              Icon="monkey.png"
              ContentTemplate="{DataTemplate views:MonkeysPage}" />

In questo esempio, MonkeysPage viene convertito da un ContentPage oggetto a , DataTemplateche viene impostato come valore della ShellContent.ContentTemplate proprietà . Ciò garantisce che MonkeysPage venga creato solo quando si verifica lo spostamento alla pagina, anziché all'avvio dell'applicazione.

Per altre informazioni sulle app shell, vedere Shell.