Bien démarrer avec XAML

Browse sample. Parcourir l’exemple

Dans une application .NET Multiplateforme App UI (.NET MAUI), XAML est principalement utilisé pour définir le contenu visuel d’une page et fonctionne avec un fichier code-behind C#. Le fichier code-behind fournit la prise en charge du code pour le balisage. Ensemble, ces deux fichiers contribuent à une nouvelle définition de classe qui inclut les vues enfants et l’initialisation des propriétés. Dans le fichier XAML, les classes et les propriétés sont référencées avec des éléments et des attributs XML, et les liens entre le balisage et le code sont établis.

Anatomie d’un fichier XAML

Une nouvelle application MAUI .NET contient trois fichiers XAML et leurs fichiers code-behind associés :

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

Le premier jumelage de fichiers est App.xaml, un fichier XAML et App.xaml.cs, un fichier code-behind C# associé au fichier XAML. App.xaml et App.xaml.cs contribuent à une classe nommée App qui dérive de Application. Le deuxième jumelage de fichiers est AppShell.xaml et AppShell.xaml.cs, qui contribuent à une classe nommée AppShell qui dérive de Shell. La plupart des autres classes avec des fichiers XAML contribuent à une classe qui dérive de ContentPage, et définissent l’interface utilisateur d’une page. Cela est vrai des fichiers MainPage.xaml et MainPage.xaml.cs .

Le fichier MainPage.xaml a la structure suivante :

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

Les deux déclarations d’espace de nomsxmlns XML () font référence aux URI sur microsoft.com. Toutefois, il n’y a pas de contenu à ces URI, et ils fonctionnent essentiellement en tant qu’identificateurs de version.

La première déclaration d’espace de noms XML signifie que les balises définies dans le fichier XAML sans préfixe font référence à des classes dans .NET MAUI, par exemple ContentPage. La deuxième déclaration d’espace de noms définit un préfixe de x. Cela est utilisé pour plusieurs éléments et attributs intrinsèques au code XAML lui-même et pris en charge par d’autres implémentations de XAML. Toutefois, ces éléments et attributs sont légèrement différents selon l’année incorporée dans l’URI. .NET MAUI prend en charge la spécification XAML 2009.

À la fin de la première balise, le x préfixe est utilisé pour un attribut nommé Class. Étant donné que l’utilisation de ce x préfixe est pratiquement universelle pour l’espace de noms XAML, les attributs XAML tels que Class sont presque toujours appelés x:Class. L’attribut x:Class spécifie un nom de classe .NET complet : la MainPage classe dans l’espace MyMauiApp de noms. Cela signifie que ce fichier XAML définit une nouvelle classe nommée MainPage dans l’espace MyMauiApp de noms qui dérive de ContentPage (balise dans laquelle l’attribut x:Class apparaît).

L’attribut x:Class peut uniquement apparaître dans l’élément racine d’un fichier XAML pour définir une classe C# dérivée. Il s’agit de la seule nouvelle classe définie dans le fichier XAML. Tout le reste qui apparaît dans un fichier XAML est simplement instancié à partir de classes existantes et initialisé.

Le fichier MainPage.xaml.cs ressemble à ceci :

namespace MyMauiApp;

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

La MainPage classe dérive de ContentPage, et est une définition de classe partielle.

Lorsque Visual Studio génère le projet, un générateur de source génère une nouvelle source C# qui contient la définition de la InitializeComponent méthode appelée à partir du MainPage constructeur et l’ajoute à l’objet de compilation.

Au moment de l’exécution, le code de la MauiProgram classe démarre l’application et exécute le App constructeur de classe, qui instancie AppShell. La AppShell classe instancie la première page de l’application à afficher, c’est-à-dire MainPage. Le MainPage constructeur appelle InitializeComponent, qui initialise tous les objets définis dans le fichier XAML, les connecte tous ensemble dans les relations parent-enfant, attache les gestionnaires d’événements définis dans le code aux événements définis dans le fichier XAML et définit l’arborescence résultante des objets comme contenu de la page.

Remarque

La AppShell classe utilise .NET MAUI Shell pour définir la première page de l’application à afficher. Toutefois, Shell dépasse la portée de cette introduction au code XAML. Pour plus d’informations, consultez .NET MAUI Shell.

Définir le contenu de la page

Un ContentPage doit contenir un enfant unique, qui peut être une vue ou une disposition avec des vues enfants. L’enfant du fichier ContentPage est automatiquement défini comme valeur de la ContentPage.Content propriété.

L’exemple suivant montre un ContentPage conteneur :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>

Dans l’exemple ci-dessus, la relation entre les classes, les propriétés et XML doit être évidente. Une classe MAUI .NET (telle que ContentPage ou Label) apparaît dans le fichier XAML en tant qu’élément XML. Les propriétés de cette classe, y compris Title sur ContentPage et sept propriétés d’un attribut XML, apparaissent généralement sous forme d’attributs Label XML.

De nombreux raccourcis existent pour définir les valeurs de ces propriétés. Certaines propriétés sont des types de données de base. Par exemple, les propriétés et les Title propriétés sont de type stringet Rotation sont de type double.Text La HorizontalTextAlignment propriété est de type TextAlignment, qui est une énumération. Pour une propriété de n’importe quel type d’énumération, tout ce que vous devez fournir est un nom de membre.

Toutefois, pour les propriétés de types plus complexes, les convertisseurs sont utilisés pour analyser le code XAML. Il s’agit de classes dans .NET MAUI qui dérivent de TypeConverter. Pour l’exemple ci-dessus, plusieurs convertisseurs MAUI .NET sont automatiquement appliqués pour convertir des valeurs de chaîne en leur type correct :

  • LayoutOptionsConverter pour la VerticalOptions propriété. Ce convertisseur convertit les noms des champs statiques publics de la LayoutOptions structure en valeurs de type LayoutOptions.
  • ColorTypeConverter pour la TextColor propriété. Ce convertisseur convertit les noms des champs statiques publics de la Colors classe ou des valeurs RVB hexadécimales, avec ou sans canal alpha.

Lorsque vous exécutez une application .NET MAUI, celle-ci MainPage s’affiche généralement. Pour afficher une autre page, vous pouvez définir cette page en tant que nouvelle page de démarrage dans le fichier AppShell.xaml ou accéder à la nouvelle page à partir de MainPage.

Pour implémenter la navigation, dans le constructeur MainPage.xaml.cs , vous pouvez créer un gestionnaire d’événements simple Button et utiliser le gestionnaire d’événements pour accéder à 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;
}

Lorsque vous compilez et déployez la nouvelle version de cette application, un bouton s’affiche à l’écran. Appuyez dessus pour accéder à HelloXamlPage:

Screenshot of rotated Label text.

Vous pouvez revenir à MainPage l’aide de la barre de navigation qui s’affiche sur chaque plateforme.

Remarque

Une alternative à ce modèle de navigation consiste à utiliser .NET MAUI Shell. Pour plus d’informations, consultez la vue d’ensemble de .NET MAUI Shell.

Interactions xaml et de code

L’enfant de la plupart ContentPage des dérivés est une disposition, telle qu’une StackLayout ou une Grid, et la disposition peut contenir plusieurs enfants. En XAML, ces relations parent-enfant sont établies avec une hiérarchie XML normale :

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

Ce fichier XAML est syntactiquement complet et produit l’interface utilisateur suivante :

Screenshot of multiple controls on a page.

Toutefois, même si vous pouvez interagir avec l’interface Slider utilisateur et Buttonque vous ne le mettez pas à jour. L’élément SliderLabel doit afficher la valeur actuelle et le Button doit faire quelque chose.

L’affichage d’une Slider valeur à l’aide d’un Label code XAML peut être entièrement obtenu en XAML avec une liaison de données. Toutefois, il est utile de voir d’abord la solution de code. Même si, la gestion du clic nécessite certainement du Button code. Cela signifie que le fichier code-behind pour XamlPlusCodePage lequel doit contenir des gestionnaires pour l’événement de l’événement ValueChangedSlider et l’événement Clicked du 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");
        }
    }
}

De retour dans le fichier XAML, les balises et Button les Slider balises doivent inclure des attributs pour les ValueChanged gestionnaires et Clicked événements qui font référence à ces gestionnaires :

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

Notez que l’affectation d’un gestionnaire à un événement a la même syntaxe que l’affectation d’une valeur à une propriété. De plus, pour que le ValueChanged gestionnaire d’événements de l’utilisateur Slider utilise la Label valeur actuelle pour afficher la valeur actuelle, le gestionnaire doit référencer cet objet à partir du code. Par conséquent, le Label nom doit être spécifié avec l’attribut x:Name . Le x préfixe de l’attribut x:Name indique que cet attribut est intrinsèque au code XAML. Le nom que vous attribuez à l’attribut x:Name a les mêmes règles que les noms de variables C#. Par exemple, il doit commencer par une lettre ou un trait de soulignement et ne contenir aucun espace incorporé.

Le ValueChanged gestionnaire d’événements peut maintenant définir la Label nouvelle Slider valeur à afficher, disponible à partir des arguments d’événement :

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

Le gestionnaire peut également obtenir l’objet Slider qui génère cet événement à partir de l’argument sender et obtenir la Value propriété à partir de ceci :

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

Le résultat est que toute manipulation des Slider causes de son affichage de sa valeur dans le Label:

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

Dans l’exemple ci-dessus, Button simule une réponse à un Clicked événement en affichant une alerte avec le Text bouton. Par conséquent, le gestionnaire d’événements peut convertir l’argument sender en un Button , puis accéder à ses propriétés :

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

La OnButtonClicked méthode est définie comme async étant parce que la DisplayAlert méthode est asynchrone et doit être précédée de l’opérateur await , qui retourne une fois la méthode terminée. Étant donné que cette méthode obtient le déclenchement de l’événement Button à partir de l’argument sender , le même gestionnaire peut être utilisé pour plusieurs boutons.

Étapes suivantes

XAML est principalement conçu pour instancier et initialiser des objets. Mais souvent, les propriétés doivent être définies sur des objets complexes qui ne peuvent pas facilement être représentés en tant que chaînes XML, et parfois les propriétés définies par une classe doivent être définies sur une classe enfant. Ces deux besoins nécessitent les fonctionnalités de syntaxe XAML essentielles des éléments de propriété et des propriétés jointes.