Share via


Erste Schritte mit XAML

Browse sample. Stichprobe durchsuchen

In einer .NET Multi-Platform App UI(.NET MAUI)-App wird XAML hauptsächlich verwendet, um den visuellen Inhalt einer Seite zu definieren und mit einer C#-CodeBehind-Datei zusammenzuarbeiten. Die CodeBehind-Datei bietet Codeunterstützung für das Markup. Zusammen tragen diese beiden Dateien zu einer neuen Klassendefinition bei, die untergeordnete Ansichten und die Initialisierung von Eigenschaften enthält. In der XAML-Datei werden Klassen und Eigenschaften mit XML-Elementen und Attributen referenziert, und es werden Verknüpfungen zwischen Markup und Code hergestellt.

Anatomie einer XAML-Datei

Eine neue .NET MAUI-App enthält drei XAML-Dateien und die zugehörigen CodeBehind-Dateien:

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

Das erste Dateienpaar ist App.xaml, eine XAML-Datei, und App.xaml.cs, eine C#-Code-Behind-Datei, die mit der XAML-Datei verknüpft ist. Sowohl App.xaml als auch App.xaml.cs tragen zu einer Klasse namens App bei, die sich von Application ableitet. Das zweite Dateipaar ist AppShell.xaml und AppShell.xaml.cs, die zu einer Klasse namens AppShell beitragen, die von Shell abgeleitet ist. Die meisten anderen Klassen mit XAML-Dateien tragen zu einer Klasse bei, die von ContentPage abgeleitet ist, und definieren die Benutzeroberfläche einer Seite. Dies gilt für die Dateien MainPage.xaml und MainPage.xaml.cs.

Die Datei MainPage.xaml hat die folgende Struktur:

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

Die beiden XML-Namespace-Deklarationen (xmlns) beziehen sich auf URIs auf microsoft.com. Diese URIs haben jedoch keinen Inhalt und dienen im Wesentlichen als Versionsbezeichner.

Die erste XML-Namespace-Deklaration bedeutet, dass in der XAML-Datei definierte Tags ohne Präfix auf Klassen in .NET MAUI verweisen, wie etwa ContentPage. Die zweite Namespace-Deklaration definiert ein Präfix von x. Dies wird für mehrere Elemente und Attribute verwendet, die für XAML selbst systemintern sind und von anderen Implementierungen von XAML unterstützt werden. Diese Elemente und Attribute unterscheiden sich jedoch geringfügig je nach Jahr, das in den URI eingebettet ist. .NET MAUI unterstützt die 2009 XAML-Spezifikation.

Am Ende des ersten Tags wird das Präfix x für ein Attribut namens Class verwendet. Da die Verwendung dieses Präfixes x für den XAML-Namespace praktisch universell ist, werden XAML-Attribute wie Class fast immer als x:Class bezeichnet. Das x:Class-Attribut spezifiziert einen voll qualifizierten .NET-Klassennamen: die MainPage-Klasse im MyMauiApp-Namespace. Das bedeutet, dass diese XAML-Datei eine neue Klasse mit dem Namen MainPage im Namespace MyMauiApp definiert, die von ContentPage (dem Tag, in dem das Attribut x:Class erscheint) abgeleitet ist.

Das x:Class-Attribut kann nur im Root-Element einer XAML-Datei erscheinen, um eine abgeleitete C#-Klasse zu definieren. Dies ist die einzige neue Klasse, die in der XAML-Datei definiert ist. Alles andere, was in einer XAML-Datei erscheint, wird stattdessen einfach aus vorhandenen Klassen instanziiert und initialisiert.

Die Datei MainPage.xaml.cs sieht ähnlich aus wie diese:

namespace MyMauiApp;

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

Die Klasse MainPage leitet sich von ContentPage ab und ist eine partielle Klassendefinition.

Wenn Visual Studio das Projekt erstellt, erzeugt ein Quellcodegenerator neuen C#-Quellcode, der die Definition der InitializeComponent-Methode enthält, die vom MainPage-Konstruktor aufgerufen wird, und fügt sie dem Kompilierungsobjekt hinzu.

Zur Laufzeit bootet der Code in der Klasse MauiProgram die Anwendung und führt den App Klassenkonstruktor aus, der AppShell instanziiert. Die Klasse AppShell instanziiert die erste Seite der anzuzeigenden App, die MainPage ist. Der MainPage-Konstruktor ruft InitializeComponent auf, der alle in der XAML-Datei definierten Objekte initialisiert, sie alle in Eltern-Kind-Beziehungen miteinander verbindet, im Code definierte Ereignishandler an die in der XAML-Datei gesetzten Ereignisse anhängt und den daraus resultierenden Baum von Objekten als Inhalt der Seite festlegt.

Hinweis

Die Klasse AppShell verwendet die .NET MAUI Shell, um die erste anzuzeigende Seite der Anwendung festzulegen. Shell würde jedoch den Rahmen dieser Einführung in XAML sprengen. Weitere Informationen finden Sie unter .NET MAUI Shell.

Inhaltsseite hinzufügen

Ein ContentPage sollte ein einzelnes untergeordnetes Element enthalten, das eine Ansicht oder ein Layout mit untergeordneten Ansichten sein kann. Das untergeordnete Element von ContentPage wird automatisch als Wert der Eigenschaft ContentPage.Content festgelegt.

Das folgende Beispiel zeigt ein ContentPage, das ein Label enthält:

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

Aus dem obigen Beispiel sollte die Beziehung zwischen Klassen, Eigenschaften und XML ersichtlich sein. Eine .NET MAUI-Klasse (wie etwa ContentPage oder Label) erscheint in der XAML-Datei als XML-Element. Eigenschaften dieser Klasse – einschließlich Title auf ContentPage und sieben Eigenschaften von Label – erscheinen normalerweise als XML-Attribute.

Viele Verknüpfungen sind vorhanden, um die Werte dieser Eigenschaften festzulegen. Einige Eigenschaften sind grundlegende Datentypen. Zum Beispiel sind die Eigenschaften Title und Text vom Typ string, und Rotation ist vom Typ double. Die HorizontalTextAlignment-Eigenschaft ist vom Typ TextAlignment, die eine Enumeration ist. Für eine Eigenschaft eines beliebigen Enumerationstyps müssen Sie lediglich einen Membernamen angeben.

Für Eigenschaften komplexerer Typen werden jedoch Konverter zum Analysieren des XAML-Codes verwendet. Dies sind Klassen in .NET MAUI, die sich von TypeConverter ableiten. Im obigen Beispiel werden mehrere .NET MAUI-Konverter automatisch angewendet, um Zeichenfolgenwerte in ihren richtigen Typ zu konvertieren:

  • LayoutOptionsConverter für die Eigenschaft VerticalOptions. Dieser Konverter wandelt die Namen der öffentlichen statischen Felder der LayoutOptions-Struktur in Werte des Typs LayoutOptions um.
  • ColorTypeConverter für die Eigenschaft TextColor. Dieser Konverter wandelt die Namen öffentlicher statischer Felder der Klasse Colors in hexadezimale RGB-Werte um, mit oder ohne Alphakanal.

Wenn Sie eine .NET MAUI-App ausführen, wird dies in der MainPage Regel angezeigt. Wenn Sie eine andere Seite anzeigen möchten, können Sie diese entweder als neue Startseite in der Datei AppShell.xaml festlegen oder über MainPage zu der neuen Seite navigieren.

Um die Navigation zu implementieren, können Sie im MainPage.xaml.cs-Konstruktor ein einfaches Button erstellen und den Event-Handler verwenden, um zu HelloXamlPage zu navigieren:

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

Wenn Sie die neue Version dieser Anwendung kompilieren und bereitstellen, erscheint eine Schaltfläche auf dem Bildschirm. Durch Drücken dieser Taste wird zu HelloXamlPage navigiert:

Screenshot of rotated Label text.

Über die Navigationsleiste, die auf jeder Plattform erscheint, können Sie zurück zu MainPage navigieren.

Hinweis

Eine Alternative zu diesem Navigationsmodell ist die Verwendung von .NET MAUI Shell. Weitere Informationen finden Sie unter .NET MAUI Shell Überblick.

XAML- und Codeinteraktionen

Das Kind der meisten ContentPage-Ableitungen ist ein Layout, wie etwa ein StackLayout oder ein Grid, und das Layout kann mehrere Kinder enthalten. In XAML werden diese Eltern-Kind-Beziehungen mit der normalen XML-Hierarchie erstellt:

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

Diese XAML-Datei ist syntaktisch vollständig und erzeugt die folgende Benutzeroberfläche:

Screenshot of multiple controls on a page.

Während Sie jedoch mit Slider und Button interagieren können, wird die Benutzeroberfläche nicht aktualisiert. Die Slider sollte die Label veranlassen, den aktuellen Wert anzuzeigen, und die Button sollte etwas tun.

Die Anzeige eines Slider-Wertes mit einem Label kann vollständig in XAML mit einer Datenbindung erreicht werden. Es ist jedoch hilfreich, die Codelösung zuerst anzuzeigen. Dennoch erfordert die Handhabung des Button-Klicks definitiv Code. Das bedeutet, dass die Code-Behind-Datei für XamlPlusCodePage Handler für das ValueChanged-Ereignis des Slider und das Clicked-Ereignis des Button enthalten muss:

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

In der XAML-Datei müssen die Tags Slider und Button Attribute für die Ereignisse ValueChanged und Clicked enthalten, die auf diese Handler verweisen:

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

Beachten Sie, dass das Zuweisen eines Handlers zu einem Ereignis dieselbe Syntax wie das Zuweisen eines Werts zu einer Eigenschaft hat. Damit der ValueChanged-Ereignishandler des Slider das Label verwenden kann, um den aktuellen Wert anzuzeigen, muss der Handler außerdem auf dieses Objekt im Code verweisen. Daher benötigt der Label einen Namen, der mit dem Attribut x:Name angegeben wird. Das x-Präfix des x:Name-Attributs zeigt an, dass dieses Attribut XAML-inhärent ist. Der Name, den Sie dem Attribut x:Name zuweisen, unterliegt denselben Regeln wie C#-Variablennamen. Er muss beispielsweise mit einem Buchstaben oder einem Unterstrich beginnen und darf keine eingebetteten Leerzeichen enthalten.

Der ValueChanged-Ereignishandler kann nun den Label so einstellen, dass er den neuen Slider-Wert anzeigt, der über die Ereignisargumente verfügbar ist:

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

Alternativ könnte der Handler das Slider-Objekt, das dieses Ereignis erzeugt, aus dem sender-Argument abrufen und die Value-Eigenschaft von diesem abrufen:

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

Das hat zur Folge, dass jede Manipulation des Slider dazu führt, dass sein Wert im Label angezeigt wird:

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

Im obigen Beispiel simuliert das Button eine Reaktion auf ein Clicked-Ereignis, indem es eine Meldung mit dem Text der Schaltfläche anzeigt. Daher kann der Ereignishandler das sender-Argument in ein Button umwandeln und dann auf dessen Eigenschaften zugreifen:

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

Die OnButtonClicked-Methode ist als async definiert, weil die DisplayAlert-Methode asynchron ist und der await-Operator vorangestellt werden sollte, der zurückkehrt, wenn die Methode abgeschlossen ist. Da diese Methode den Button, der das Ereignis auslöst, aus dem sender-Argument erhält, kann derselbe Handler für mehrere Schaltflächen verwendet werden.

Nächste Schritte

XAML wurde hauptsächlich zum Instanziieren und Initialisieren von Objekten entwickelt. Eigenschaften müssen jedoch häufig auf komplexe Objekte festgelegt werden, die nicht einfach als XML-Zeichenfolgen dargestellt werden können, und manchmal müssen Eigenschaften, die von einer Klasse definiert werden, für eine untergeordnete Klasse festgelegt werden. Diese beiden Anforderungen erfordern die grundlegenden XAML-Syntaxmerkmale von Eigenschaftselementen und angehängten Eigenschaften.