Condividi tramite


Introduzione a XAML

Browse sample. Esplorare l'esempio

In un'app .NET Multipiattaforma App UI (.NET MAUI) XAML viene usato principalmente per definire il contenuto visivo di una pagina e funziona insieme a un file code-behind C#. Il file code-behind fornisce il supporto del codice per il markup. Insieme, questi due file contribuiscono a una nuova definizione di classe che include visualizzazioni figlio e inizializzazione delle proprietà. All'interno del file XAML, alle classi e alle proprietà viene fatto riferimento con elementi e attributi XML e vengono stabiliti collegamenti tra markup e codice.

Anatomia di un file XAML

Una nuova app MAUI .NET contiene tre file XAML e i relativi file code-behind associati:

Screenshot of the structure of a new .NET MAUI app.

La prima associazione di file è App.xaml, un file XAML e App.xaml.cs, un file code-behind C# associato al file XAML. Sia App.xaml che App.xaml.cs contribuiscono a una classe denominata App che deriva da Application. La seconda associazione di file è AppShell.xaml e AppShell.xaml.cs, che contribuiscono a una classe denominata AppShell che deriva da Shell. La maggior parte delle altre classi con file XAML contribuisce a una classe che deriva da ContentPagee definisce l'interfaccia utente di una pagina. Questo vale per i file MainPage.xaml e MainPage.xaml.cs .

Il file MainPage.xaml ha la struttura seguente:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyMauiApp.MainPage">
    ...
</ContentPage>

Le due dichiarazioni dello spazio dei nomi XML (xmlns) fanno riferimento agli URI in microsoft.com. Tuttavia, non sono presenti contenuti in questi URI e funzionano fondamentalmente come identificatori di versione.

La prima dichiarazione dello spazio dei nomi XML indica che i tag definiti all'interno del file XAML senza prefisso fanno riferimento alle classi in .NET MAUI, ad esempio ContentPage. La seconda dichiarazione dello spazio dei nomi definisce un prefisso di x. Viene usato per diversi elementi e attributi intrinseci di XAML e supportati da altre implementazioni di XAML. Tuttavia, questi elementi e attributi sono leggermente diversi a seconda dell'anno incorporato nell'URI. .NET MAUI supporta la specifica XAML 2009.

Alla fine del primo tag, il x prefisso viene usato per un attributo denominato Class. Poiché l'uso di questo x prefisso è praticamente universale per lo spazio dei nomi XAML, gli attributi XAML come Class sono quasi sempre definiti .x:Class L'attributo x:Class specifica un nome di classe .NET completo: la MainPage classe nello spazio dei MyMauiApp nomi . Questo significa che questo file XAML definisce una nuova classe denominata MainPage nello MyMauiApp spazio dei nomi che deriva da ContentPage (il tag in cui viene visualizzato l'attributo x:Class ).

L'attributo x:Class può essere visualizzato solo nell'elemento radice di un file XAML per definire una classe C# derivata. Questa è l'unica nuova classe definita nel file XAML. Tutto il resto visualizzato in un file XAML viene invece semplicemente creata un'istanza da classi esistenti e inizializzata.

Il file MainPage.xaml.cs è simile al seguente:

namespace MyMauiApp;

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

La MainPage classe deriva da ContentPagee è una definizione di classe parziale.

Quando Visual Studio compila il progetto, un generatore di origine genera una nuova origine C# contenente la definizione del InitializeComponent metodo chiamato dal MainPage costruttore e lo aggiunge all'oggetto di compilazione.

In fase di esecuzione, il MauiProgram codice nella classe esegue il bootstrap dell'app ed esegue il costruttore della classe , che crea AppShellun'istanza App di . La AppShell classe crea un'istanza della prima pagina dell'app da visualizzare, ovvero MainPage. Il MainPage costruttore chiama InitializeComponent, che inizializza tutti gli oggetti definiti nel file XAML, li connette tutti insieme nelle relazioni padre-figlio, associa i gestori eventi definiti nel codice agli eventi impostati nel file XAML e imposta l'albero risultante degli oggetti come contenuto della pagina.

Nota

La AppShell classe usa .NET MAUI Shell per impostare la prima pagina dell'app da visualizzare. Tuttavia, Shell esula dall'ambito di questa introduzione a XAML. Per altre informazioni, vedere Shell MAUI .NET.

Impostare il contenuto della pagina

Un ContentPage oggetto deve contenere un singolo elemento figlio, che può essere una visualizzazione o un layout con visualizzazioni figlio. L'elemento ContentPage figlio di viene impostato automaticamente come valore della ContentPage.Content proprietà .

Nell'esempio seguente viene illustrato un oggetto ContentPage contenente un oggetto Label:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.HelloXamlPage"
             Title="Hello XAML Page">
    <Label Text="Hello, XAML!"
           VerticalOptions="Center"
           HorizontalTextAlignment="Center"
           Rotation="-15"
           FontSize="18"
           FontAttributes="Bold"
           TextColor="Blue" />
</ContentPage>

Nell'esempio precedente la relazione tra classi, proprietà e XML deve essere evidente. Una classe MAUI .NET (ad esempio ContentPage o Label) viene visualizzata nel file XAML come elemento XML. Le proprietà di tale classe, incluse in TitleContentPage e sette proprietà di Label vengono in genere visualizzate come attributi XML.

Esistono molti collegamenti per impostare i valori di queste proprietà. Alcune proprietà sono tipi di dati di base. Ad esempio, le Title proprietà e Text sono di tipo stringe Rotation è di tipo double. La HorizontalTextAlignment proprietà è di tipo TextAlignment, che è un'enumerazione . Per una proprietà di qualsiasi tipo di enumerazione, è sufficiente specificare un nome membro.

Per le proprietà di tipi più complessi, tuttavia, i convertitori vengono usati per l'analisi del codice XAML. Si tratta di classi in .NET MAUI che derivano da TypeConverter. Per l'esempio precedente, diversi convertitori MAUI .NET vengono applicati automaticamente per convertire i valori stringa nel tipo corretto:

  • LayoutOptionsConverter per la VerticalOptions proprietà . Questo convertitore converte i nomi dei campi statici pubblici della LayoutOptions struttura in valori di tipo LayoutOptions.
  • ColorTypeConverter per la TextColor proprietà . Questo convertitore converte i nomi dei campi statici pubblici della Colors classe o dei valori RGB esadecimali, con o senza un canale alfa.

Quando si esegue un'app MAUI .NET, viene MainPage in genere visualizzato . Per visualizzare una pagina diversa, è possibile impostarla come nuova pagina di avvio nel file AppShell.xaml oppure passare alla nuova pagina da MainPage.

Per implementare la navigazione, nel costruttore MainPage.xaml.cs è possibile creare un gestore eventi semplice Button e usare il gestore eventi per passare a HelloXamlPage:

public MainPage()
{
    InitializeComponent();

    Button button = new Button
    {
        Text = "Navigate!",
        HorizontalOptions = LayoutOptions.Center,
        VerticalOptions = LayoutOptions.Center
    };

    button.Clicked += async (sender, args) =>
    {
        await Navigation.PushAsync(new HelloXamlPage());
    };

    Content = button;
}

Quando si compila e si distribuisce la nuova versione di questa app, viene visualizzato un pulsante sullo schermo. Premendo si passa a HelloXamlPage:

Screenshot of rotated Label text.

È possibile tornare a MainPage usando la barra di spostamento visualizzata in ogni piattaforma.

Nota

Un'alternativa a questo modello di navigazione consiste nell'usare .NET MAUI Shell. Per altre informazioni, vedere Panoramica della shell MAUI di .NET.

Interazioni con XAML e codice

L'elemento figlio della maggior parte ContentPage dei derivati è un layout, ad esempio o StackLayout , Gride il layout può contenere più elementi figlio. In XAML queste relazioni padre-figlio vengono stabilite con la normale gerarchia XML:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.XamlPlusCodePage"
             Title="XAML + Code Page">
    <StackLayout>
        <Slider VerticalOptions="Center" />
        <Label Text="A simple Label"
               FontSize="18"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <Button Text="Click Me!"
                HorizontalOptions="Center"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

Questo file XAML è sintatticamente completo e produce l'interfaccia utente seguente:

Screenshot of multiple controls on a page.

Tuttavia, mentre è possibile interagire con Slider e Button, l'interfaccia utente non viene aggiornata. Deve Slider fare in modo che l'oggetto Label visualizzi il valore corrente e deve eseguire un'operazione Button .

La visualizzazione di un Slider valore tramite un Label oggetto può essere ottenuta interamente in XAML con un data binding. Tuttavia, è utile vedere prima la soluzione di codice. Anche in questo caso, la gestione del Button clic richiede sicuramente il codice. Ciò significa che il file code-behind per XamlPlusCodePage deve contenere gestori per l'evento ValueChanged di Slider e l'evento Clicked di Button:

namespace XamlSamples
{
    public partial class XamlPlusCodePage
    {
        public XamlPlusCodePage()
        {
            InitializeComponent();
        }

        void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
        {
            valueLabel.Text = args.NewValue.ToString("F3");
        }

        async void OnButtonClicked(object sender, EventArgs args)
        {
            Button button = (Button)sender;
            await DisplayAlert("Clicked!", "The button labeled '" + button.Text + "' has been clicked", "OK");
        }
    }
}

Nel file XAML i Slider tag e Button devono includere attributi per gli ValueChanged eventi e Clicked che fanno riferimento a questi gestori:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.XamlPlusCodePage"
             Title="XAML + Code Page">
    <StackLayout>
        <Slider VerticalOptions="Center"
                ValueChanged="OnSliderValueChanged" />
        <Label x:Name="valueLabel"
               Text="A simple Label"
               FontSize="18"
               HorizontalOptions="Center"
               VerticalOptions="Center" />
        <Button Text="Click Me!"
                HorizontalOptions="Center"
                VerticalOptions="Center"
                Clicked="OnButtonClicked" />
    </StackLayout>
</ContentPage>

Si noti che l'assegnazione di un gestore a un evento ha la stessa sintassi dell'assegnazione di un valore a una proprietà. Inoltre, affinché il ValueChanged gestore eventi dell'oggetto Slider usi Label per visualizzare il valore corrente, il gestore deve fare riferimento a tale oggetto dal codice. Pertanto, richiede Label un nome, specificato con l'attributo x:Name . Il x prefisso dell'attributo x:Name indica che questo attributo è intrinseco a XAML. Il nome assegnato all'attributo x:Name ha le stesse regole dei nomi delle variabili C#. Ad esempio, deve iniziare con una lettera o un carattere di sottolineatura e non contenere spazi incorporati.

Il ValueChanged gestore eventi può ora impostare per Label visualizzare il nuovo Slider valore, disponibile dagli argomenti dell'evento:

void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
    valueLabel.Text = args.NewValue.ToString("F3");
}

In alternativa, il gestore può ottenere l'oggetto Slider che genera questo evento dall'argomento sender e ottenere la Value proprietà da tale oggetto:

void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
    valueLabel.Text = ((Slider)sender).Value.ToString("F3");
}

Il risultato è che qualsiasi manipolazione dell'oggetto Slider determina la visualizzazione del relativo valore in Label:

Screenshot of multiple controls on a page, with Slider value displayed.

Nell'esempio precedente simula Button una risposta a un Clicked evento visualizzando un avviso con il Text pulsante . Pertanto, il gestore eventi può eseguire il cast dell'argomento sender a e Button quindi accedere alle relative proprietà:

async void OnButtonClicked(object sender, EventArgs args)
{
    Button button = (Button)sender;
    await DisplayAlert("Clicked!", "The button labeled '" + button.Text + "' has been clicked", "OK");
}

Il OnButtonClicked metodo viene definito come async perché il DisplayAlert metodo è asincrono e deve essere preceduto dall'operatore await , che restituisce al termine del metodo . Poiché questo metodo ottiene la generazione dell'evento Button dall'argomento sender , lo stesso gestore può essere usato per più pulsanti.

Passaggi successivi

XAML è progettato principalmente per la creazione di istanze e l'inizializzazione di oggetti. Spesso, tuttavia, le proprietà devono essere impostate su oggetti complessi che non possono essere facilmente rappresentati come stringhe XML e talvolta le proprietà definite da una classe devono essere impostate su una classe figlio. Queste due esigenze richiedono le funzionalità di sintassi XAML essenziali degli elementi delle proprietà e delle proprietà associate.