Utilizzo di estensioni di markup XAML

Download Sample Scaricare l'esempio

Le estensioni di markup XAML consentono di migliorare la potenza e la flessibilità di XAML consentendo l'impostazione degli attributi degli elementi da un'ampia gamma di origini. 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. Questo articolo illustra le estensioni di markup seguenti:

  • x:Static : fare riferimento a proprietà statiche, campi o membri di enumerazione.
  • x:Reference : fare riferimento agli elementi denominati nella pagina.
  • x:Type : impostare un attributo su un System.Type oggetto .
  • x:Array : costruire una matrice di oggetti di un particolare tipo.
  • x:Null : impostare un attributo su un null valore.
  • OnPlatform : personalizzare l'aspetto dell'interfaccia utente in base alla piattaforma.
  • OnIdiom : personalizzare l'aspetto dell'interfaccia utente in base al linguaggio del dispositivo in cui è in esecuzione l'applicazione.
  • DataTemplate : converte un tipo in un oggetto DataTemplate.
  • FontImage : visualizza un'icona del carattere in qualsiasi visualizzazione in grado di visualizzare un oggetto ImageSource.
  • AppThemeBinding : utilizzare una risorsa in base al tema di sistema corrente.

Altre estensioni di markup XAML sono state storicamente supportate da altre implementazioni XAML e sono supportate anche da Xamarin.Forms. Questi sono descritti più in dettaglio in altri articoli:

  • StaticResource - fare riferimento agli oggetti di un dizionario risorse, come descritto nell'articolo Dizionari risorse.
  • DynamicResource : rispondere alle modifiche apportate agli oggetti in un dizionario risorse, come descritto nell'articolo Stili dinamici.
  • Binding : stabilire un collegamento tra le proprietà di due oggetti, come descritto nell'articolo Data Binding.
  • TemplateBinding: esegue il data binding da un modello di controllo, come descritto nei modelli di controllo dell'articoloXamarin.Forms.
  • RelativeSource : imposta l'origine dell'associazione in relazione alla posizione della destinazione di associazione, come illustrato nell'articolo Associazioni relative.

Il RelativeLayout layout usa l'estensione ConstraintExpressiondi markup personalizzata . Questa estensione di markup è descritta nell'articolo RelativeLayout.

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 comune per usare x:Static consiste nel definire prima una classe con alcune costanti o variabili statiche, ad esempio questa piccola AppConstants classe nel programma MarkupExtensions :

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

La pagina x:Static Demo illustra diversi modi per usare l'estensione di x:Static markup. L'approccio più dettagliato crea un'istanza della StaticExtension classe tra Label.FontSize tag di elemento proprietà:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             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 operazione può essere ulteriormente semplificata, ma la modifica introduce una nuova sintassi: consiste nell'inserire la StaticExtension classe e l'impostazione 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}" />

Si noti che 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.

La pagina Demo statica contiene altri due esempi. Il tag radice del file XAML contiene una dichiarazione dello spazio dei nomi XML per lo spazio dei nomi .NET System :

xmlns:sys="clr-namespace:System;assembly=netstandard"

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

Nell'esempio finale viene visualizzato il Device.RuntimePlatform valore . La Environment.NewLine proprietà statica viene utilizzata per inserire un carattere di nuova riga tra i due Span oggetti:

<Label HorizontalTextAlignment="Center"
       FontSize="{x:Static local:AppConstants.NormalFontSize}">
    <Label.FormattedText>
        <FormattedString>
            <Span Text="Runtime Platform: " />
            <Span Text="{x:Static sys:Environment.NewLine}" />
            <Span Text="{x:Static Device.RuntimePlatform}" />
        </FormattedString>
    </Label.FormattedText>
</Label>

Ecco l'esempio in esecuzione:

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, descritti in modo più dettagliato nell'articolo Associazione dati.

La pagina x:Reference Demo mostra due usi di x:Reference con i 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://xamarin.com/schemas/2014/forms"
             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="CenterAndExpand"
               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="CenterAndExpand" />

    </StackLayout>
</ContentPage>

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 di Binding markup. Si noti che le Source impostazioni e StringFormat sono separate da virgole. Ecco il programma in esecuzione:

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 impostata su un nome di classe o struttura. L'estensione x:Type di markup restituisce l'oggetto System.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.

All'interno Xamarin.Formsdi sono disponibili diverse proprietà con argomenti di tipo Type. Gli esempi includono la TargetType proprietà di Stylee l'attributo x:TypeArguments usato per specificare argomenti nelle classi generiche. Tuttavia, il parser XAML esegue automaticamente l'operazione typeof e l'estensione x:Type di markup non viene usata in questi casi.

Un punto in cui x:Typeè necessario è con l'estensione x:Array di markup, descritta nella sezione successiva.

L'estensione x:Type di markup è utile anche quando si costruisce un menu in cui ogni voce di menu corrisponde a un oggetto di un particolare tipo. È possibile associare un Type oggetto a ogni voce di menu e quindi creare un'istanza dell'oggetto quando viene selezionata la voce di menu.

Questo è il funzionamento del menu di spostamento nel MainPageprogramma Estensioni di markup. Il file MainPage.xaml contiene un oggetto TableView con ognuno TextCell corrispondente a una determinata pagina del programma:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MarkupExtensions"
             x:Class="MarkupExtensions.MainPage"
             Title="Markup Extensions"
             Padding="10">
    <TableView Intent="Menu">
        <TableRoot>
            <TableSection>
                <TextCell Text="x:Static Demo"
                          Detail="Access constants or statics"
                          Command="{Binding NavigateCommand}"
                          CommandParameter="{x:Type local:StaticDemoPage}" />

                <TextCell Text="x:Reference Demo"
                          Detail="Reference named elements on the page"
                          Command="{Binding NavigateCommand}"
                          CommandParameter="{x:Type local:ReferenceDemoPage}" />

                <TextCell Text="x:Type Demo"
                          Detail="Associate a Button with a Type"
                          Command="{Binding NavigateCommand}"
                          CommandParameter="{x:Type local:TypeDemoPage}" />

                <TextCell Text="x:Array Demo"
                          Detail="Use an array to fill a ListView"
                          Command="{Binding NavigateCommand}"
                          CommandParameter="{x:Type local:ArrayDemoPage}" />

                ···                          

        </TableRoot>
    </TableView>
</ContentPage>

Ecco la pagina principale di apertura in Estensioni di markup:

Main Page

Ogni CommandParameter proprietà è impostata su un'estensione x:Type di markup che fa riferimento a una delle altre pagine. La Command proprietà è associata a una proprietà denominata NavigateCommand. Questa proprietà è definita nel MainPage file code-behind:

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();

        NavigateCommand = new Command<Type>(async (Type pageType) =>
        {
            Page page = (Page)Activator.CreateInstance(pageType);
            await Navigation.PushAsync(page);
        });

        BindingContext = this;
    }

    public ICommand NavigateCommand { private set; get; }
}

La NavigateCommand proprietà è un oggetto che implementa un Command comando execute con un argomento di tipo Type , ovvero il valore di CommandParameter. Il metodo usa Activator.CreateInstance per creare un'istanza della pagina e quindi passarvi. Il costruttore termina impostando la BindingContext proprietà della pagina su se stessa, che consente il funzionamento dell'oggetto Binding on Command . Per altre informazioni su questo tipo di codice, vedere l'articolo Data Binding e in particolare l'articolo Relativo all'esecuzionedi comandi.

La pagina x:Type Demo usa una tecnica simile per creare un'istanza degli Xamarin.Forms elementi e aggiungerli a un oggetto StackLayout. Il file XAML è inizialmente costituito da tre Button elementi con le relative Command proprietà impostate su e Binding le CommandParameter proprietà impostate su tipi di tre Xamarin.Forms visualizzazioni:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             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="CenterAndExpand"
                Command="{Binding CreateCommand}"
                CommandParameter="{x:Type Slider}" />

        <Button Text="Create a Stepper"
                HorizontalOptions="Center"
                VerticalOptions="CenterAndExpand"
                Command="{Binding CreateCommand}"
                CommandParameter="{x:Type Stepper}" />

        <Button Text="Create a Switch"
                HorizontalOptions="Center"
                VerticalOptions="CenterAndExpand"
                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 TypeDemoPage()
    {
        InitializeComponent();

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

        BindingContext = this;
    }

    public ICommand CreateCommand { private set; get; }
}

Il metodo eseguito quando viene premuto un Button oggetto crea una nuova istanza dell'argomento, ne imposta la VerticalOptions proprietà e la aggiunge all'oggetto StackLayout. I tre Button elementi 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.
  • 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. Impostare la Type proprietà su un'estensione x:Type di markup.

La pagina x:Array Demo mostra come usare x:Array per aggiungere elementi a un ListView oggetto impostando la ItemsSource proprietà su una matrice:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             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>        

Crea ViewCell una semplice BoxView voce di colore per ogni voce di colore:

x:Array Demo

Esistono diversi modi per specificare i singoli Color elementi in questa matrice. È possibile usare un'estensione x:Static di markup:

<x:Static Member="Color.Blue" />

In alternativa, è possibile usare StaticResource per recuperare un colore da un dizionario risorse:

<StaticResource Key="myColor" />

Verso la fine di questo articolo, vedrai un'estensione di markup XAML personalizzata che crea anche un nuovo valore di colore:

<local:HslColor H="0.5" S="1.0" L="0.5" />

Quando si definiscono matrici di tipi comuni come stringhe o numeri, usare i tag elencati nell'articolo Passing Constructor Arguments (Argomenti del costruttore di passaggio) per delimitare i valori.

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'estensione x:Null di markup è raramente necessaria e raramente usata, ma se si trova una necessità, si sarà contenti che esista.

La pagina x:Null Demo illustra uno scenario quando x:Null potrebbe risultare utile. Si supponga di definire un oggetto implicito Style per Label che includa un Setter oggetto che imposta la FontFamily proprietà su un nome di famiglia dipendente dalla piattaforma:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MarkupExtensions.NullDemoPage"
             Title="x:Null Demo">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Label">
                <Setter Property="FontSize" Value="48" />
                <Setter Property="FontFamily">
                    <Setter.Value>
                        <OnPlatform x:TypeArguments="x:String">
                            <On Platform="iOS" Value="Times New Roman" />
                            <On Platform="Android" Value="serif" />
                            <On Platform="UWP" Value="Times New Roman" />
                        </OnPlatform>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <ContentPage.Content>
        <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.Content>
</ContentPage>   

Si scopre quindi che per uno degli Label elementi si desidera che tutte le impostazioni delle proprietà nell'oggetto implicito Style , ad eccezione di FontFamily, che si vuole essere il valore predefinito. È possibile definire un altro Style per tale scopo, ma un approccio più semplice consiste semplicemente nell'impostare la FontFamily proprietà del particolare Label su x:Null, come illustrato nel centro Label.

Ecco il programma in esecuzione:

x:Null Demo

Si noti che quattro elementi Label hanno un tipo di carattere serif, ma il centro Label ha il tipo di carattere sans-serif predefinito.

Estensione di markup OnPlatform

L'estensione di markup OnPlatform consente di personalizzare l'aspetto dell'interfaccia utente per ogni piattaforma. Offre le stesse funzionalità delle OnPlatform classi e On , ma con una rappresentazione più concisa.

L'estensione OnPlatform di markup è supportata dalla OnPlatformExtension classe , che definisce le proprietà seguenti:

  • Default di tipo object, impostato su un valore predefinito da applicare alle proprietà che rappresentano le piattaforme.
  • Android di tipo object, impostato su un valore da applicare in Android.
  • GTK di tipo object, impostato su un valore da applicare alle piattaforme GTK.
  • iOS di tipo object, impostato su un valore da applicare in iOS.
  • macOS di tipo object, impostato su un valore da applicare in macOS.
  • Tizen di tipo object, impostato su un valore da applicare alla piattaforma Tizen.
  • UWPdi tipo object, impostato su un valore da applicare al piattaforma UWP (Universal Windows Platform).
  • WPF di tipo object, impostato su un valore da applicare alla piattaforma Windows Presentation Foundation.
  • Converter di tipo IValueConverter, che può essere impostato su un'implementazione IValueConverter .
  • ConverterParameter di tipo object, che può essere impostato su un valore da passare all'implementazione IValueConverter .

Nota

Il parser XAML consente di abbreviatare la OnPlatformExtension classe come OnPlatform.

La Default proprietà è la proprietà content di OnPlatformExtension. Pertanto, per le espressioni di markup XAML espresse con parentesi graffe, puoi eliminare la Default= parte dell'espressione purché sia il primo argomento. Se la Default proprietà non è impostata, per impostazione predefinita verrà usato il valore della BindableProperty.DefaultValue proprietà , purché l'estensione di markup sia destinata a un oggetto BindableProperty.

Importante

Il parser XAML prevede che i valori del tipo corretto vengano forniti alle proprietà che utilizzano l'estensione di OnPlatform markup. Se è necessaria la conversione dei tipi, l'estensione OnPlatform di markup tenterà di eseguirla usando i convertitori predefiniti forniti da Xamarin.Forms. Tuttavia, esistono alcune conversioni di tipo che non possono essere eseguite dai convertitori predefiniti e in questi casi la Converter proprietà deve essere impostata su un'implementazione IValueConverter .

La pagina Demo OnPlatform mostra come usare l'estensione OnPlatform di markup:

<BoxView Color="{OnPlatform Yellow, iOS=Red, Android=Green, UWP=Blue}"
         WidthRequest="{OnPlatform 250, iOS=200, Android=300, UWP=400}"  
         HeightRequest="{OnPlatform 250, iOS=200, Android=300, UWP=400}"
         HorizontalOptions="Center" />

In questo esempio tutte e tre OnPlatform le espressioni usano la versione abbreviata del nome della OnPlatformExtension classe. Le tre OnPlatform estensioni di markup impostano le Colorproprietà , WidthRequeste HeightRequest di BoxView su valori diversi in iOS, Android e UWP. Le estensioni di markup forniscono anche valori predefiniti per queste proprietà sulle piattaforme non specificate, eliminando la Default= parte dell'espressione. Si noti che le proprietà dell'estensione di markup impostate sono separate da virgole.

Ecco il programma in esecuzione:

OnPlatform Demo

Estensione di markup OnIdiom

L'estensione OnIdiom di markup consente di personalizzare l'aspetto dell'interfaccia utente in base al linguaggio del dispositivo in cui è in esecuzione l'applicazione. È supportato dalla OnIdiomExtension classe , che definisce le proprietà seguenti:

  • Default di tipo object, impostato su un valore predefinito da applicare alle proprietà che rappresentano idiomi del dispositivo.
  • Phone di tipo object, impostato su un valore da applicare ai telefoni.
  • Tablet di tipo object, impostato su un valore da applicare ai tablet.
  • Desktop di tipo object, impostato su un valore da applicare sulle piattaforme desktop.
  • TV di tipo object, impostato su un valore da applicare sulle piattaforme TV.
  • Watch di tipo object, impostato su un valore da applicare nelle piattaforme Espressione di controllo.
  • Converter di tipo IValueConverter, che può essere impostato su un'implementazione IValueConverter .
  • ConverterParameter di tipo object, che può essere impostato su un valore da passare all'implementazione IValueConverter .

Nota

Il parser XAML consente di abbreviatare la OnIdiomExtension classe come OnIdiom.

La Default proprietà è la proprietà content di OnIdiomExtension. Pertanto, per le espressioni di markup XAML espresse con parentesi graffe, puoi eliminare la Default= parte dell'espressione purché sia il primo argomento.

Importante

Il parser XAML prevede che i valori del tipo corretto vengano forniti alle proprietà che utilizzano l'estensione di OnIdiom markup. Se è necessaria la conversione dei tipi, l'estensione OnIdiom di markup tenterà di eseguirla usando i convertitori predefiniti forniti da Xamarin.Forms. Tuttavia, esistono alcune conversioni di tipo che non possono essere eseguite dai convertitori predefiniti e in questi casi la Converter proprietà deve essere impostata su un'implementazione IValueConverter .

La pagina Demo OnIdiom mostra come usare l'estensione OnIdiom di markup:

<BoxView Color="{OnIdiom Yellow, Phone=Red, Tablet=Green, Desktop=Blue}"
         WidthRequest="{OnIdiom 100, Phone=200, Tablet=300, Desktop=400}"
         HeightRequest="{OnIdiom 100, Phone=200, Tablet=300, Desktop=400}"
         HorizontalOptions="Center" />

In questo esempio tutte e tre OnIdiom le espressioni usano la versione abbreviata del nome della OnIdiomExtension classe. Le tre OnIdiom estensioni di markup impostano le Colorproprietà , WidthRequeste HeightRequest di BoxView su valori diversi nel telefono, nel tablet e nei linguaggi desktop. Le estensioni di markup forniscono anche valori predefiniti per queste proprietà nei termini non specificati, eliminando la Default= parte dell'espressione. Si noti che le proprietà dell'estensione di markup impostate sono separate da virgole.

Ecco il programma in esecuzione:

OnIdiom 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 applicazioni Shell, vedere Xamarin.Forms Shell.

Estensione del markup FontImage

L'estensione FontImage di markup consente di visualizzare un'icona del carattere in qualsiasi visualizzazione in grado di visualizzare un oggetto ImageSource. Fornisce la stessa funzionalità della FontImageSource classe , ma con una rappresentazione più concisa.

L'estensione FontImage di markup è supportata dalla FontImageExtension classe , che definisce le proprietà seguenti:

  • FontFamily di tipo string, la famiglia di caratteri a cui appartiene l'icona del carattere.
  • Glyph di tipo string, il valore del carattere Unicode dell'icona del tipo di carattere.
  • Color di tipo Color, il colore da utilizzare durante la visualizzazione dell'icona del carattere.
  • Size di tipo double, la dimensione, in unità indipendenti dal dispositivo, dell'icona del tipo di carattere di cui è stato eseguito il rendering. Il valore predefinito è 30. Inoltre, questa proprietà può essere impostata su una dimensione del carattere denominata.

Nota

Il parser XAML consente di abbreviatare la FontImageExtension classe come FontImage.

La Glyph proprietà è la proprietà content di FontImageExtension. Pertanto, per le espressioni di markup XAML espresse con parentesi graffe, puoi eliminare la Glyph= parte dell'espressione purché sia il primo argomento.

La pagina Demo FontImage mostra come usare l'estensione di FontImage markup:

<Image BackgroundColor="#D1D1D1"
       Source="{FontImage &#xf30c;, FontFamily={OnPlatform iOS=Ionicons, Android=ionicons.ttf#}, Size=44}" />

In questo esempio, la versione abbreviata del nome della FontImageExtension classe viene usata per visualizzare un'icona XBox, dalla famiglia di tipi dicaratterei, in un oggetto Image. L'espressione usa anche l'estensione OnPlatform di markup per specificare valori di proprietà diversi FontFamily in iOS e Android. Inoltre, la Glyph= parte dell'espressione viene eliminata e le proprietà dell'estensione di markup impostate sono separate da virgole. Si noti che mentre il carattere Unicode per l'icona è \uf30c, deve essere preceduto da un carattere di escape in XAML e quindi diventa &#xf30c;.

Ecco il programma in esecuzione:

Screenshot of the FontImage markup extension

Per informazioni sulla visualizzazione delle icone dei tipi di carattere specificando i dati dell'icona del carattere in un FontImageSource oggetto, vedere Visualizzare le icone dei tipi di carattere.

Estensione di markup AppThemeBinding

L'estensione AppThemeBinding di markup consente di specificare una risorsa da utilizzare, ad esempio un'immagine o un colore, in base al tema di sistema corrente.

Importante

L'estensione AppThemeBinding di markup ha requisiti minimi del sistema operativo. Per altre informazioni, vedere Rispondere alle modifiche dei temi di sistema nelle Xamarin.Forms applicazioni.

L'estensione AppThemeBinding di markup è supportata dalla AppThemeBindingExtension classe , che definisce le proprietà seguenti:

  • Default, di tipo object, impostato sulla risorsa da usare per impostazione predefinita.
  • Light, di tipo object, impostato sulla risorsa da usare quando il dispositivo usa il tema chiaro.
  • Dark, di tipo object, impostato sulla risorsa da usare quando il dispositivo usa il tema scuro.
  • Value, di tipo object, che restituisce la risorsa attualmente usata dall'estensione di markup.

Nota

Il parser XAML consente di abbreviatare la AppThemeBindingExtension classe come AppBindingTheme.

La Default proprietà è la proprietà content di AppThemeBindingExtension. Pertanto, per le espressioni di markup XAML espresse con parentesi graffe, puoi eliminare la Default= parte dell'espressione purché sia il primo argomento.

La pagina Demo AppThemeBinding mostra come usare l'estensione AppThemeBinding di markup:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MarkupExtensions.AppThemeBindingDemoPage"
             Title="AppThemeBinding Demo">
    <ContentPage.Resources>

        <Style x:Key="labelStyle"
               TargetType="Label">
            <Setter Property="TextColor"
                    Value="{AppThemeBinding Black, Light=Blue, Dark=Teal}" />
        </Style>

    </ContentPage.Resources>
    <StackLayout Margin="20">
        <Label Text="This text is green in light mode, and red in dark mode."
               TextColor="{AppThemeBinding Light=Green, Dark=Red}" />
        <Label Text="This text is black by default, blue in light mode, and teal in dark mode."
               Style="{StaticResource labelStyle}" />
    </StackLayout>
</ContentPage>

In questo esempio, il colore del testo del primo Label è impostato su verde quando il dispositivo usa il tema chiaro e viene impostato su rosso quando il dispositivo usa il tema scuro. Il secondo Label ha la proprietà TextColor impostata tramite un oggetto Style. In questo Style modo il colore del testo dell'oggetto Label su nero viene impostato su blu quando il dispositivo usa il tema chiaro e su teal quando il dispositivo usa il tema scuro.

Ecco il programma in esecuzione:

AppThemeBinding Demo

Definire le estensioni di markup

Se hai riscontrato la necessità di un'estensione di markup XAML non disponibile in Xamarin.Forms, puoi creare un'estensione personalizzata.