Freigeben über


Erstellen einer .NET MAUI-App

In diesem Lernprogramm wird veranschaulicht, wie Sie eine .NET Multi-Platform App UI (.NET MAUI)-App erstellen, die nur plattformübergreifenden Code verwendet. Der von Ihnen geschriebene Code ist also nicht spezifisch für Windows, Android, iOS oder macOS. Die App, die Sie erstellen, ist eine Notizen-App, in der der Benutzer mehrere Notizen erstellen, speichern und laden kann.

In diesem Tutorial lernen Sie Folgendes:

  • Erstellen einer .NET MAUI-Shell-App
  • Führen Sie Ihre App auf Ihrer ausgewählten Plattform aus.
  • Definieren Sie die Benutzeroberfläche mit der eXtensible Application Markup Language (XAML) und interagieren Sie mit XAML-Elementen über Code.
  • Erstellen Sie Ansichten und binden Sie sie an Daten.
  • Verwenden Sie die Navigation, um zu und von Seiten zu wechseln.

Sie verwenden Visual Studio 2022, um eine Anwendung zu erstellen, mit der Sie eine Notiz eingeben und im Gerätespeicher speichern können. Die endgültige Anwendung wird hier gezeigt:

Letzter Screenshot der Notizen-App mit der Auflistung der Notizen. Letzter Screenshot der Notizen-App, Hinzufügen einer Notiz.

Erstellen eines Projekts

Bevor Sie mit diesem Tutorial beginnen, lesen Sie den Artikel Erstellen Sie Ihre erste App. Verwenden Sie beim Erstellen des Projekts die folgenden Einstellungen:

  • Projektname

    Dieser muss auf Notes festgelegt werden. Wenn das Projekt einen anderen Namen hat, kann der Code, den Sie aus diesem Lernprogramm kopieren und einfügen, zu Buildfehlern führen.

  • Lösung und Projekt im selben Verzeichnis platzieren

    Deaktivieren Sie diese Einstellung.

Setzen Sie den Namen des .NET MAUI-Projekts in Visual Studio auf Notes.

Wählen Sie beim Erstellen Des Projekts die neueste .NET-Version aus.

Auswählen des Zielgeräts

.NET MAUI-Apps sind für die Ausführung auf mehreren Betriebssystemen und Geräten konzipiert. Sie müssen auswählen, mit welchem Ziel Sie Ihre App testen und debuggen möchten.

Legen Sie das Debugziel in der Visual Studio-Symbolleiste auf das Gerät fest, mit dem Sie debuggen und testen möchten. Die folgenden Schritte zeigen, wie das Debugziel in Android festgelegt wird:

Auswählen des Android-Debug-Ziels für eine .NET MAUI-App in Visual Studio.

  1. Wählen Sie die Dropdown-Schaltfläche Debugziel.
  2. Wählen Sie den Punkt Android-Emulatoren.
  3. Wählen Sie das Emulatorgerät aus.

Anpassen der App-Shell

Wenn Visual Studio ein .NET MAUI-Projekt erstellt, werden vier wichtige Codedateien generiert. Diese sind im Bereich Projektmappen-Explorer von Visual Studio zu sehen:

Der Projektmappen-Explorer zeigt die Dateien für ein .NET MAUI-Projekt in Visual Studio.

Diese Dateien helfen beim Konfigurieren und Ausführen der .NET MAUI-App. Jede Datei dient einem anderen Zweck, wie unten beschrieben:

  • MauiProgram.cs

    Dies ist eine Codedatei, die Ihre Anwendung bootet. Der Code in dieser Datei dient als plattformübergreifender Einstiegspunkt der App, der die App konfiguriert und startet. Der Startcode der Vorlage verweist auf die App-Klasse, die in der Datei App.xaml definiert ist.

  • App.xaml und App.xaml.cs

    Nur um die Dinge einfach zu halten, werden beide Dateien als einzelne Datei bezeichnet. Im Allgemeinen gibt es zwei Dateien mit jeder XAML-Datei, die .xaml-Datei selbst und eine entsprechende Codedatei, die ein untergeordnetes Element der Datei im Projektmappen-Explorer ist. Die Datei .xaml enthält das XAML-Markup und die Codedatei enthält den vom Benutzer erstellten Code zur Interaktion mit dem XAML-Markup.

    Die Datei App.xaml enthält anwendungsübergreifende XAML-Ressourcen, wie z. B. Farben, Stile oder Vorlagen. Die Datei App.xaml.cs enthält im Allgemeinen Code, der die Shell-Anwendung instanziiert. In diesem Projekt verweist sie auf die Klasse AppShell.

  • AppShell.xaml und AppShell.xaml.cs

    Diese Datei definiert die Klasse AppShell, die zur Definition der visuellen Hierarchie der Anwendung verwendet wird.

  • MainPage.xaml und MainPage.xaml.cs

    Dies ist die Startseite, die von der App angezeigt wird. Die Datei MainPage.xaml definiert die UI (Benutzeroberfläche) der Seite. MainPage.xaml.cs enthält den Code-Behind für die XAML, z. B. den Code für ein Schaltflächenklickereignis.

Eine "Über"-Seite hinzufügen

Die erste Anpassung, die Sie vornehmen werden, ist das Hinzufügen einer weiteren Seite zu dem Projekt. Diese Seite ist eine "Über"-Seite, die Informationen über diese App enthält, z. B. den Autor, die Version und vielleicht einen Link zu weiteren Informationen.

  1. Klicken Sie im Projektmappen-Explorer-Bereich von Visual Studio mit der rechten Maustaste auf das Notizenprojekt> "Neues Element>".

    Klicken Sie mit der rechten Maustaste auf ein Projekt in Visual Studio und wählen Sie Neues Element.

  2. Im Dialog Neues Element hinzufügen wählen Sie .NET MAUI in der Vorlagenliste auf der linken Seite des Fensters. Wählen Sie dann die Vorlage .NET MAUI ContentPage (XAML). Nennen Sie die Datei AboutPage.xaml, und wählen Sie dann Hinzufügen.

    Hinzufügen einer neuen ContentPage zum Projekt. Die ContentPage heißt AboutPage.xaml.

  3. Die Datei AboutPage.xaml öffnet eine neue Dokument-Registerkarte und zeigt das gesamte XAML-Markup an, das die Benutzeroberfläche der Seite darstellt. Ersetzen des XAML-Markups durch folgendes Markup:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Notes.AboutPage">
        <VerticalStackLayout Spacing="10" Margin="10">
            <HorizontalStackLayout Spacing="10">
                <Image Source="dotnet_bot.png"
                       SemanticProperties.Description="The dot net bot waving hello!"
                       HeightRequest="64" />
                <Label FontSize="22" FontAttributes="Bold" Text="Notes" VerticalOptions="End" />
                <Label FontSize="22" Text="v1.0" VerticalOptions="End" />
            </HorizontalStackLayout>
    
            <Label Text="This app is written in XAML and C# with .NET MAUI." />
            <Button Text="Learn more..." Clicked="LearnMore_Clicked" />
        </VerticalStackLayout>
    </ContentPage>
    
  4. Speichern Sie die Datei durch Drücken von CTRL+S oder durch Auswahl des Menüs Datei>Speichern AboutPage.xaml.

Lassen Sie uns die wichtigsten Teile der XAML-Steuerelemente auf der Seite aufgliedern:

  • <ContentPage> ist das Stammobjekt für die Klasse AboutPage.

  • <VerticalStackLayout> ist das einzige untergeordnete Objekt von ContentPage. ContentPage kann nur ein untergeordnetes Objekt haben. Der VerticalStackLayout-Typ kann mehrere untergeordnete Elemente aufweisen. Dieses Layoutsteuerelement ordnet seine untergeordneten Elemente vertikal nacheinander an.

  • <HorizontalStackLayout> funktioniert genauso wie ein <VerticalStackLayout>, außer dass die untergeordneten Elemente horizontal angeordnet sind.

  • <Image> zeigt ein Bild an, in diesem Fall wird das dotnet_bot.png-Bild verwendet, das im Lieferumfang jedes .NET MAUI-Projekts enthalten ist.

    Von Bedeutung

    Die dem Projekt hinzugefügte Datei ist eigentlich dotnet_bot.svg. .NET MAUI konvertiert Scalable Vector Graphics (SVG)-Dateien in Portable Network Graphic (PNG)-Dateien auf Basis des Zielgeräts. Wenn Sie also eine SVG-Datei zu Ihrem .NET MAUI App-Projekt hinzufügen, sollte sie von XAML oder C# aus mit einer .png-Erweiterung verwiesen werden. Der einzige Verweis auf die SVG-Datei sollte sich in Ihrer Projektdatei befinden.

  • <Label>-Steuerelemente zeigen Text an.

  • <Button>-Steuerelemente können von Benutzer*innen gedrückt werden, wodurch das Ereignis Clicked ausgelöst wird. Sie können Code als Reaktion auf das Clicked-Ereignis ausführen.

  • Clicked="LearnMore_Clicked"

    Das Clicked-Ereignis der Schaltfläche wird dem LearnMore_Clicked-Ereignishandler zugewiesen, der in der CodeBehind-Datei definiert wird. Sie erstellen diesen Code im nächsten Schritt.

Behandeln des Klick-Ereignisses

Der nächste Schritt besteht darin, den Code für das Clicked-Ereignis der Schaltfläche hinzuzufügen.

  1. Erweitern Sie im Bereich Solution Explorer von Visual Studio die Datei AboutPage.xaml, um die zugehörige CodeBehind-Datei AboutPage.xaml.cs anzuzeigen. Doppelklicken Sie dann auf die Datei AboutPage.xaml.cs, um sie im Code-Editor zu öffnen.

    Ein Bild des Projektmappen-Explorer-Fensters in Visual Studio mit einem roten Rahmen, der das Symbol zum Erweitern hervorhebt.

  2. Fügen Sie den folgenden LearnMore_Clicked-Ereignishandlercode hinzu, der den Systembrowser mit einer bestimmten URL öffnet:

    private async void LearnMore_Clicked(object sender, EventArgs e)
    {
        // Navigate to the specified URL in the system browser.
        await Launcher.Default.OpenAsync("https://aka.ms/maui");
    }
    

    Beachten Sie, dass der Methodendeklaration das Schlüsselwort async hinzugefügt wurde, das die Verwendung des Schlüsselworts await beim Öffnen des Systembrowsers ermöglicht.

  3. Speichern Sie die Datei durch Drücken von STRG+S oder durch Auswahl des Menüs Datei>AboutPage.xaml.cs speichern.

Nun, da die XAML und der CodeBehind der AboutPage vollständig sind, müssen Sie sie in der App anzeigen lassen.

Hinzufügen von Bildressourcen

Einige Steuerelemente können Bilder verwenden, wodurch die Interaktion der Benutzer*innen mit Ihrer App verbessert wird. In diesem Abschnitt laden Sie zwei Bilder herunter, die Sie in Ihrer App verwenden, zusammen mit zwei alternativen Bildern für die Verwendung mit iOS.

Laden Sie die folgenden Bilder herunter:

Nachdem Sie die Bilder heruntergeladen haben, können Sie sie mit dem Datei-Explorer in den Ordner Resources\Images des Projekts verschieben. Jede Datei in diesem Ordner wird automatisch als MauiImage-Ressource in das Projekt aufgenommen. Sie können auch Visual Studio verwenden, um die Bilder zu Ihrem Projekt hinzuzufügen. Wenn Sie die Bilder manuell verschieben, überspringen Sie das folgende Verfahren.

Von Bedeutung

Überspringen Sie nicht das Herunterladen der iOS-spezifischen Bilder, sie sind für die Durchführung dieses Tutorials erforderlich.

Verschieben der Bilder mit Visual Studio

  1. Erweitern Sie im Bereich Projektmappen-Explorer von Visual Studio den Ordner Ressourcen. Daraufhin wird der Ordner Bilder angezeigt.

    Tipp

    Sie können den Datei-Explorer verwenden, um die Bilder direkt in den Bereich Projektmapen-Explorer zu ziehen, der sich über dem Ordner Bilder befindet. Dadurch werden die Dateien automatisch in den Ordner verschoben und in das Projekt eingeschlossen. Wenn Sie sich dafür entscheiden, die Dateien per Drag & Drop zu platzieren, ignorieren Sie den Rest dieses Verfahrens.

  2. Klicken Sie mit der rechten Maustaste auf "Bilder", und wählen Sie "Vorhandenes Element> aus.

  3. Navigieren Sie zu dem Ordner, der die heruntergeladenen Bilder enthält.

  4. Ändern Sie den Dateitypfilter in Bilddateien.

  5. Halten Sie STRG gedrückt und klicken Sie auf jedes der Bilder, die Sie heruntergeladen haben, dann drücken Sie Hinzufügen.

Fügen Sie vier Symbolbilder zum .NET MAUI Projekt hinzu.

Ändern der App-Shell

Wie zu Beginn dieses Artikels erwähnt, definiert die AppShell-Klasse die visuelle Hierarchie einer App, das XAML-Markup, das bei der Erstellung der Benutzeroberfläche der App verwendet wird. Aktualisieren Sie den XAML-Code, um ein TabBar-Steuerelement hinzuzufügen:

  1. Doppelklicken Sie auf die Datei AppShell.xaml im Bereich Projektmappen-Explorer, um den XAML-Editor zu öffnen. Ersetzen Sie das XAML-Markup durch den folgenden Code:

    <?xml version="1.0" encoding="UTF-8" ?>
    <Shell
        x:Class="Notes.AppShell"
        xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:local="clr-namespace:Notes"
        Shell.FlyoutBehavior="Disabled">
    
        <TabBar>
            <ShellContent
                Title="Notes"
                ContentTemplate="{DataTemplate local:MainPage}"
                Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />
    
            <ShellContent
                Title="About"
                ContentTemplate="{DataTemplate local:AboutPage}"
                Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
        </TabBar>
    
    </Shell>
    
  2. Speichern Sie die Datei durch Drücken von STRG+S oder durch Auswahl des Menüs Datei>AppShell.xaml speichern.

Lassen Sie uns die wichtigsten Teile des XAML-Codes aufschlüsseln:

  • <Shell> ist das Stammobjekt des XAML-Markups.
  • <TabBar> ist der Inhalt der Shell.
  • Zwei <ShellContent>-Objekte innerhalb der <TabBar>. Bevor Sie den Vorlagencode ersetzt haben, gab es ein einziges <ShellContent>-Objekt, das auf die MainPage-Seite verwies.

Die TabBar und ihre untergeordneten Elemente stellen keine Elemente der Benutzeroberfläche dar, sondern die Organisation der visuellen Hierarchie der App. Shell verwendet diese Objekte und erzeugt die Benutzeroberfläche für den Inhalt, wobei oben eine Leiste für jede Seite steht. Die ShellContent.Icon-Eigenschaft für jede Seite verwendet die OnPlatform Markuperweiterung. Diese XAML-Markuperweiterung wird verwendet, um unterschiedliche Werte für verschiedene Plattformen anzugeben. In diesem Beispiel verwendet jede Plattform standardmäßig das symbol icon_about.png, aber iOS und MacCatalyst verwenden icon_about_ios.png.

Jedes <ShellContent>-Objekt verweist auf eine Seite, die angezeigt werden soll. Hierfür wird die Eigenschaft ContentTemplate festgelegt.

App starten

Führen Sie die App aus, indem Sie F5 oder die Wiedergabetaste am oberen Rand von Visual Studio drücken:

Die Schaltfläche Debug Target von Visual Studio mit dem Text Windows Machine.

Sie werden sehen, dass es zwei Registerkarten gibt: Hinweise und Info. Drücken Sie die Registerkarte Info und die App navigiert zu dem von Ihnen erstellten AboutPage. Drücken Sie die Schaltfläche "Weitere Informationen ", um den Webbrowser zu öffnen.

Über-Seite des .NET MAUI App-Tutorials.

Schließen Sie die App, und kehren Sie zu Visual Studio zurück. Wenn Sie den Android-Emulator verwenden, beenden Sie die App auf dem virtuellen Gerät, oder drücken Sie die Stopptaste oben in Visual Studio:

Die Schaltfläche Debugging anhalten von Visual Studio.

Erstellen einer Seite für eine Notiz

Nun, da die App die MainPage und AboutPage enthält, können Sie mit der Erstellung des restlichen Teils der App beginnen. Zuerst erstellen Sie eine Seite, die es Benutzer*innen ermöglicht, eine Notiz zu erstellen und anzuzeigen, und dann schreiben Sie den Code, um die Notiz zu laden und zu speichern.

Auf der Notizseite wird die Notiz angezeigt, und Sie können sie entweder speichern oder löschen. Fügen Sie zunächst die neue Seite zum Projekt hinzu:

  1. Klicken Sie im Projektmappen-Explorer-Bereich von Visual Studio mit der rechten Maustaste auf das Notizenprojekt> "Neues Element>".

  2. Im Dialog Neues Element hinzufügen wählen Sie .NET MAUI in der Vorlagenliste auf der linken Seite des Fensters. Wählen Sie dann die Vorlage .NET MAUI ContentPage (XAML). Nennen Sie die Datei NotePage.xaml, und wählen Sie dann Hinzufügen.

  3. Die Datei NotePage.xaml wird in einer neuen Registerkarte geöffnet und zeigt das gesamte XAML-Markup an, das die Benutzeroberfläche der Seite darstellt. Ersetzen Sie das XAML-Code-Markup durch das folgende Markup:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Notes.NotePage"
                 Title="Note">
        <VerticalStackLayout Spacing="10" Margin="5">
            <Editor x:Name="TextEditor"
                    Placeholder="Enter your note"
                    HeightRequest="100" />
    
            <Grid ColumnDefinitions="*,*" ColumnSpacing="4">
                <Button Text="Save"
                        Clicked="SaveButton_Clicked" />
    
                <Button Grid.Column="1"
                        Text="Delete"
                        Clicked="DeleteButton_Clicked" />
            </Grid>
        </VerticalStackLayout>
    </ContentPage>
    
  4. Speichern Sie die Datei durch Drücken von Strg + S oder durch Auswahl des Menüs Datei>NotePage.xaml speichern.

Lassen Sie uns die wichtigsten Teile der XAML-Steuerelemente auf der Seite aufgliedern:

  • <VerticalStackLayout> ordnet seine untergeordneten Steuerelemente vertikal untereinander an.

  • <Editor> ist ein mehrzeiliges Texteditor-Steuerelement und ist das erste Steuerelement innerhalb von VerticalStackLayout.

  • <Grid> ist ein Layout-Steuerelement und ist das zweite Steuerelement innerhalb von VerticalStackLayout.

    Dieses Steuerelement definiert Spalten und Zeilen zum Erstellen von Zellen. Untergeordnete Steuerelemente werden in diesen Zellen platziert.

    Standardmäßig enthält das Steuerelement Grid eine einzelne Zeile und Spalte, wodurch eine einzelne Zelle erstellt wird. Spalten werden mit einer Breite definiert, und der Wert * für die Breite besagt, dass die Spalte so viel Platz wie möglich ausfüllen soll. Im vorherigen Ausschnitt wurden zwei Spalten definiert, die beide so viel Platz wie möglich beanspruchen, wodurch die Spalten gleichmäßig auf den zugewiesenen Platz verteilt werden: ColumnDefinitions="*,*". Die Spaltengrößen werden durch ein ,-Zeichen getrennt.

    Spalten und Zeilen, die von einem Grid definiert werden, werden beginnend bei 0 indiziert. Die erste Spalte wäre also Index 0, die zweite Spalte ist Index 1 usw.

  • Zwei <Button>-Steuerelemente befinden sich innerhalb der <Grid> und sind einer Spalte zugeordnet. Wenn ein untergeordnetes Steuerelement keine Spaltenzuweisung definiert, wird es automatisch der ersten Spalte zugewiesen. In diesem Markup ist die erste Schaltfläche die Schaltfläche "Speichern", die automatisch der ersten Spalte, Spalte 0, zugewiesen wird. Die zweite Schaltfläche ist die Schaltfläche "Löschen", die der zweiten Spalte (Spalte 1) zugewiesen ist.

    Beachten Sie, dass die beiden Schaltflächen das Clicked-Ereignis behandelt haben. Sie fügen den Code für diese Handler im nächsten Abschnitt hinzu.

Laden und Speichern einer Notiz

Öffnen Sie die Code-Behind-Datei NotePage.xaml.cs. Sie können den Code-Behind für die Datei NotePage.xaml auf drei Arten öffnen:

  • Wenn die NotePage.xaml geöffnet und das aktive, bearbeitete Dokument ist, drücken Sie F7.
  • Wenn die NotePage.xaml geöffnet und das aktive, bearbeitete Dokument ist, klicken Sie mit der rechten Maustaste in den Texteditor und wählen Sie Code anzeigen aus.
  • Verwenden Sie den Projektmappen-Explorer, um den Eintrag NotePage.xaml zu erweitern, wodurch die Datei NotePage.xaml.cs sichtbar wird. Doppelklicken Sie auf die Datei, um sie zu öffnen.

Wenn Sie eine neue XAML-Datei hinzufügen, enthält der Code-Behind eine einzige Zeile im Konstruktor, einen Aufruf der InitializeComponent-Methode:

namespace Notes;

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

Die InitializeComponent-Methode liest das XAML-Markup und initialisiert alle vom Markup definierten Objekte. Die Objekte sind in ihrer verschachtelten Beziehung miteinander verbunden und die im Code definierten Event-Handler werden an die in der XAML festgelegten Ereignisse angehängt.

Nachdem Sie nun ein wenig mehr über Code-Behind-Dateien erfahren haben, fügen Sie der Code-Behind-Datei NotePage.xaml.cs Code hinzu, um das Laden und Speichern von Notizen zu behandeln.

  1. Wenn eine Notiz erstellt wird, wird sie als Textdatei auf dem Gerät gespeichert. Der Name der Datei wird durch die _fileName-Variable dargestellt. Fügen Sie die folgende string-Variablendeklaration in die NotePage-Klasse ein:

    public partial class NotePage : ContentPage
    {
        string _fileName = Path.Combine(FileSystem.AppDataDirectory, "notes.txt");
    

    Der obige Code erstellt einen Pfad zu der Datei und speichert sie im lokalen Datenverzeichnis der App. Der Dateiname ist notes.txt.

  2. Lesen Sie im Konstruktor der Klasse, nachdem die InitializeComponent-Methode aufgerufen wurde, die Datei vom Gerät und speichern Sie ihren Inhalt in der TextEditor-Eigenschaft des Text-Steuerelements:

    public NotePage()
    {
        InitializeComponent();
    
        if (File.Exists(_fileName))
            TextEditor.Text = File.ReadAllText(_fileName);
    }
    
  3. Als Nächstes fügen Sie den Code für die Behandlung der in der XAML definierten Clicked-Ereignisse hinzu:

    private void SaveButton_Clicked(object sender, EventArgs e)
    {
        // Save the file.
        File.WriteAllText(_fileName, TextEditor.Text);
    }
    
    private void DeleteButton_Clicked(object sender, EventArgs e)
    {
        // Delete the file.
        if (File.Exists(_fileName))
            File.Delete(_fileName);
    
        TextEditor.Text = string.Empty;
    }
    

    Die Methode SaveButton_Clicked schreibt den Text im Editor-Steuerelement in die Datei, die durch die Variable _fileName dargestellt wird.

    Die DeleteButton_Clicked-Methode prüft zunächst, ob die durch die _fileName-Variable dargestellte Datei existiert, und löscht sie, falls sie existiert. Anschließend wird der Text des Editor-Steuerelements gelöscht.

  4. Speichern Sie die Datei durch Drücken von Strg + S oder durch Auswahl des Menüs Datei>Speichern von NotePage.xaml.cs.

Der letzte Code für die CodeBehind-Datei sollte wie folgt aussehen:

namespace Notes;

public partial class NotePage : ContentPage
{
    string _fileName = Path.Combine(FileSystem.AppDataDirectory, "notes.txt");

    public NotePage()
    {
        InitializeComponent();

        if (File.Exists(_fileName))
            TextEditor.Text = File.ReadAllText(_fileName);
    }

    private void SaveButton_Clicked(object sender, EventArgs e)
    {
        // Save the file.
        File.WriteAllText(_fileName, TextEditor.Text);
    }

    private void DeleteButton_Clicked(object sender, EventArgs e)
    {
        // Delete the file.
        if (File.Exists(_fileName))
            File.Delete(_fileName);

        TextEditor.Text = string.Empty;
    }
}

Testen der Notiz

Nachdem die Notizseite fertig ist, benötigen Sie eine Möglichkeit, sie dem Benutzer zu präsentieren. Öffnen Sie die Datei AppShell.xaml und ändern Sie den ersten ShellContent-Eintrag, sodass er auf NotePage statt auf MainPage verweist:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="Notes.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:Notes"
    Shell.FlyoutBehavior="Disabled">

    <TabBar>
        <ShellContent
            Title="Notes"
            ContentTemplate="{DataTemplate local:NotePage}"
            Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />

        <ShellContent
            Title="About"
            ContentTemplate="{DataTemplate local:AboutPage}"
            Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
    </TabBar>

</Shell>

Speichern Sie die Datei und führen Sie die App aus. Versuchen Sie, etwas in das Eingabefeld einzutippen, und drücken Sie die Schaltfläche Speichern. Schließen Sie die App und öffnen Sie sie erneut. Die eingegebene Notiz sollte aus dem Speicher des Geräts geladen werden.

Seite für die Eingabe von Notizen in der .NET MAUI Anwendung.

Binden von Daten an die Benutzeroberfläche und Navigieren in Seiten

In diesem Teil des Lernprogramms werden die Konzepte von Ansichten, Modellen und in der App-Navigation vorgestellt.

In den vorherigen Schritten des Lernprogramms haben Sie dem Projekt zwei Seiten hinzugefügt: NotePage und AboutPage. Die Seiten stellen eine Datenansicht dar. Die NotePage ist eine "Ansicht", die "Notizdaten" anzeigt, und die AboutPage ist eine "Ansicht", die "App-Informationsdaten" anzeigt. In beiden Ansichten ist ein Modell dieser Daten fest einkodiert oder eingebettet, und Sie müssen das Datenmodell von der Ansicht trennen.

Welchen Vorteil hat das Trennen des Modells von der Ansicht? Sie können die Ansicht so entwerfen, dass sie einen beliebigen Teil des Modells darstellt und damit interagiert, ohne sich Gedanken über den tatsächlichen Code machen zu müssen, der das Modell implementiert. Dies wird mithilfe der Datenbindung erreicht, was später in diesem Lernprogramm vorgestellt wird. Jetzt lässt sich das Projekt jedoch neu strukturieren.

Trennen der Ansicht und des Modells

Refaktorieren Sie den bestehenden Code, um das Modell von der Ansicht zu trennen. Die nächsten Schritte organisieren den Code, sodass Ansichten und Modelle getrennt voneinander definiert werden.

  1. Löschen Sie MainPage.xaml und MainPage.xaml.cs aus Ihrem Projekt, sie werden nicht mehr benötigt. Suchen Sie im Bereich Projektmappen-Explorer den Eintrag für MainPage.xaml, klicken Sie mit der rechten Maustaste darauf, und wählen Sie Löschen aus.

    Tipp

    Das Löschen des Elements MainPage.xaml sollte auch das Element MainPage.xaml.cs löschen. Wenn MainPage.xaml.cs nicht gelöscht wurde, klicken Sie mit der rechten Maustaste darauf und wählen Löschen.

  2. Klicken Sie mit der rechten Maustaste auf das Notes Projekt und wählen Sie Hinzufügen>Neuer Ordner. Geben Sie dem Ordner den Namen Models.

  3. Klicken Sie mit der rechten Maustaste auf das Notes Projekt und wählen Sie Hinzufügen>Neuer Ordner. Geben Sie dem Ordner den Namen Views.

  4. Suchen Sie das Element NotePage.xaml und ziehen Sie es in den Ordner Views. Die NotePage.xaml.cs sollte mit ihm verschoben werden.

    Von Bedeutung

    Wenn Sie eine Datei verschieben, fordert Visual Studio Sie in der Regel mit einer Warnung dazu auf, wie der Verschiebungsvorgang eine lange Zeit in Anspruch nehmen kann. Dies sollte hier kein Problem sein, drücken Sie OK, wenn Sie diese Warnung sehen.

    In Visual Studio werden Sie möglicherweise auch gefragt, ob Sie den Namespace der verschobenen Datei anpassen möchten. Wählen Sie Nein, da die nächsten Schritte den Namespace ändern werden.

  5. Suchen Sie das Element AboutPage.xaml und ziehen Sie es in den Ordner Views. Die AboutPage.xaml.cs sollte mit ihm verschoben werden.

Aktualisieren des Namespace der Ansicht

Jetzt, da die Ansichten in den Views Ordner verschoben wurden, müssen Sie die Namespaces entsprechend aktualisieren. Der Namespace für die XAML- und Code-Behind-Dateien der Seiten ist auf Notes festgelegt. Das muss auf Notes.Views aktualisiert werden.

  1. Erweitern Sie im Bereich Projektmappen-Explorer sowohl NotePage.xaml als auch AboutPage.xaml, um die Code-Behind-Dateien anzuzeigen:

    Das Notes-Projekt mit dem Ordner Ansichten und den erweiterten Seitenansichten.

  2. Doppelklicken Sie auf das Element NotePage.xaml.cs, um den Code-Editor zu öffnen. Ändern Sie den Namespace in Notes.Views.

    namespace Notes.Views;
    
  3. Wiederholen Sie die vorherigen Schritte für das Element AboutPage.xaml.cs.

  4. Doppelklicken Sie auf das Element NotePage.xaml, um den XAML-Editor zu öffnen. Auf den alten Namespace wird über das x:Class-Attribut verwiesen, auf das definiert wird, welcher Klassentyp der CodeBehind für den XAML-Code ist. Dieser Eintrag ist nicht nur der Namespace, sondern der Namespace mit dem Typ. Ändern Sie den Wert von x:Class zu Notes.Views.NotePage:

    x:Class="Notes.Views.NotePage"
    
  5. Wiederholen Sie den vorherigen Schritt für das Element AboutPage.xaml, aber setzen Sie den Wert x:Class auf Notes.Views.AboutPage.

Beheben der Namespace-Referenz in Shell

Die AppShell.xaml definiert zwei Registerkarten, eine für die NotesPage und eine für AboutPage. Da diese beiden Seiten in einen neuen Namespace verschoben wurden, ist die Typzuordnung im XAML-Code jetzt ungültig. Doppelklicken Sie im Bereich Projektmappen-Explorer auf den Eintrag AppShell.xaml, um ihn im XAML-Editor zu öffnen. Sie sollte wie der folgende Ausschnitt aussehen:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="Notes.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:Notes"
    Shell.FlyoutBehavior="Disabled">

    <TabBar>
        <ShellContent
            Title="Notes"
            ContentTemplate="{DataTemplate local:NotePage}"
            Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />

        <ShellContent
            Title="About"
            ContentTemplate="{DataTemplate local:AboutPage}"
            Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
    </TabBar>

</Shell>

Ein .NET-Namespace wird über eine XML-Namespacedeklaration in den XAML-Code importiert. Im vorherigen XAML-Markup ist es das Attribut xmlns:local="clr-namespace:Notes" im Stammelement: <Shell>. Das Format der Deklarierung eines XML-Namespace zum Importieren eines .NET-Namespace in derselben Assembly lautet:

xmlns:{XML namespace name}="clr-namespace:{.NET namespace}"

Die vorherige Deklaration bildet also den XML-Namespace local auf den .NET-Namespace Notes ab. Es ist gängige Praxis, den Namen local dem Stammnamespace Ihres Projekts zuzuordnen.

Entfernen Sie den local XML-Namespace, und fügen Sie einen neuen hinzu. Dieser neue XML Namespace wird auf den .NET Namespace Notes.Views abgebildet, also nennen Sie ihn views. Die Deklaration sollte wie das folgende Attribut aussehen: xmlns:views="clr-namespace:Notes.Views".

Der local XML-Namespace wurde von den ShellContent.ContentTemplate-Eigenschaften verwendet, ändern Sie sie in views. Ihr XAML sollte nun wie der folgende Ausschnitt aussehen:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="Notes.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:views="clr-namespace:Notes.Views"
    Shell.FlyoutBehavior="Disabled">

    <TabBar>
        <ShellContent
            Title="Notes"
            ContentTemplate="{DataTemplate views:NotePage}"
            Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />

        <ShellContent
            Title="About"
            ContentTemplate="{DataTemplate views:AboutPage}"
            Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
    </TabBar>

</Shell>

Sie sollten jetzt in der Lage sein, die App ohne Compilerfehler auszuführen, und alles sollte wie zuvor funktionieren.

Definieren des Modells

Derzeit ist das Modell die Daten, die in die Notiz und zu Ansichten eingebettet sind. Wir erstellen neue Klassen, um diese Daten darzustellen. Zuerst stellt das Modell die Daten einer Notizseite dar:

  1. Klicken Sie im Projektmappen-Explorer-Bereich mit der rechten Maustaste auf den Models Ordner, und wählen Sie Hinzufügen>Klasse aus.

  2. Nennen Sie die Klasse Note.cs und drücken Sie Hinzufügen.

  3. Öffnen Sie die Datei Program.cs, und ersetzen Sie den Code durch Folgendes:

    namespace Notes.Models;
    
    internal class Note
    {
        public string Filename { get; set; }
        public string Text { get; set; }
        public DateTime Date { get; set; }
    }
    
  4. Speichern Sie die Datei.

Erstellen Sie als Nächstes das Modell der Seite:

  1. Klicken Sie im Projektmappen-Explorer-Bereich mit der rechten Maustaste auf den Models Ordner, und wählen Sie Hinzufügen>Klasse aus.

  2. Nennen Sie die Klasse About.cs und drücken Sie Hinzufügen.

  3. Öffnen Sie About.cs und ersetzen Sie den Code durch den folgenden Ausschnitt:

    namespace Notes.Models;
    
    internal class About
    {
        public string Title => AppInfo.Name;
        public string Version => AppInfo.VersionString;
        public string MoreInfoUrl => "https://aka.ms/maui";
        public string Message => "This app is written in XAML and C# with .NET MAUI.";
    }
    
  4. Speichern Sie die Datei.

Aktualisieren der Info-Seite

Die Info-Seite lässt sich am schnellsten aktualisieren, und Sie können die Anwendung ausführen und sehen, wie sie Daten aus dem Modell lädt.

  1. Öffnen Sie im Fensterbereich Projektmappen-Explorer die Datei Views\AboutPage.xaml.

  2. Ersetzen Sie den Inhalt durch den folgenden Ausschnitt:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:models="clr-namespace:Notes.Models"
                 x:Class="Notes.Views.AboutPage"
                 x:DataType="models:About">
        <ContentPage.BindingContext>
            <models:About />
        </ContentPage.BindingContext>
        <VerticalStackLayout Spacing="10" Margin="10">
            <HorizontalStackLayout Spacing="10">
                <Image Source="dotnet_bot.png"
                       SemanticProperties.Description="The dot net bot waving hello!"
                       HeightRequest="64" />
                <Label FontSize="22" FontAttributes="Bold" Text="{Binding Title}" VerticalOptions="End" />
                <Label FontSize="22" Text="{Binding Version}" VerticalOptions="End" />
            </HorizontalStackLayout>
    
            <Label Text="{Binding Message}" />
            <Button Text="Learn more..." Clicked="LearnMore_Clicked" />
        </VerticalStackLayout>
    
    </ContentPage>
    

Sehen wir uns die geänderten Zeilen an, die im vorherigen Codeausschnitt hervorgehoben sind:

  • xmlns:models="clr-namespace:Notes.Models"

    Diese Zeile ordnet den Notes.Models .NET-Namespace dem models XML-Namespace zu.

  • x:DataType="models:About"

    Diese Zeile weist den XAML-Compiler an, alle Bindungsausdrücke für eine höhere Laufzeitleistung zu kompilieren und die Bindungsausdrücke für den Notes.Models.About Typ aufzulösen.

  • Die BindingContext-Eigenschaft der ContentPage-Klasse wird mithilfe des XML-Namespaces und des Objekts der Note.Models.About-Klasse auf eine Instanz der models:About-Klasse festgelegt. Dies wurde mit der Syntax eines Eigenschaftselements statt eines XML-Attributs festgelegt.

    Von Bedeutung

    Bisher wurden Eigenschaften mithilfe eines XML-Attributs festgelegt. Dies eignet sich hervorragend für einfache Werte, z. B. eine Label.FontSize-Eigenschaft. Wenn der Eigenschaftswert jedoch komplexer ist, müssen Sie die Eigenschaftselement-Syntax verwenden, um das Objekt zu erstellen. Betrachten Sie das folgende Beispiel für das Erstellen einer Bezeichnung mit dem FontSize-Eigenschaftensatz:

    <Label FontSize="22" />
    

    Die gleiche FontSize-Eigenschaft kann mit der Eigenschaftselement-Syntax eingestellt werden:

    <Label>
        <Label.FontSize>
            22
        </Label.FontSize>
    </Label>
    
  • Bei drei <Label>-Steuerelementen wurde der Text-Eigenschaftswert von einer festcodierten Zeichenfolge in eine Bindungssyntax geändert: {Binding PATH}.

    Die {Binding}-Syntax wird zur Laufzeit verarbeitet, sodass der von der Bindung zurückgegebene Wert dynamisch sein kann. Der PATH-Teil von {Binding PATH} ist der Eigenschaftspfad, an den gebunden werden soll. Die Eigenschaft stammt aus dem BindingContext des aktuellen Steuerelements. Bei der Steuerung <Label> ist BindingContext nicht eingestellt. Der Kontext wird vom übergeordneten Objekt geerbt, wenn er vom Steuerelement nicht gesetzt wird. In diesem Fall ist das übergeordnete Objekt, das den Kontext setzt, das Stammobjekt: ContentPage.

    Das Objekt in BindingContext ist eine Instanz des Modells About. Der Bindungspfad einer der Beschriftungen bindet die Eigenschaft Label.Text an die Eigenschaft About.Title.

Die letzte Änderung an der Info-Seite ist die Aktualisierung der Schaltfläche, die eine Webseite öffnet. Die URL wurde im Code-Behind hartkodiert, aber die URL sollte aus dem Modell stammen, das in der Eigenschaft BindingContext enthalten ist.

  1. Öffnen Sie im Fensterbereich Projektmappen-Explorer die Datei Views\AboutPage.xaml.cs.

  2. Ersetzen Sie die LearnMore_Clicked-Methode durch folgenden Code:

    private async void LearnMore_Clicked(object sender, EventArgs e)
    {
        if (BindingContext is Models.About about)
        {
            // Navigate to the specified URL in the system browser.
            await Launcher.Default.OpenAsync(about.MoreInfoUrl);
        }
    }
    

Wenn Sie die hervorgehobene Zeile betrachten, überprüft der Code, ob es BindingContext sich um einen Models.About Typ handelt, und weist sie about der Variablen zu. Die nächste Zeile innerhalb der if-Anweisung öffnet den Browser mit der URL, die durch die about.MoreInfoUrl-Eigenschaft bereitgestellt wird.

Führen Sie die App aus, und Sie sollten sehen, dass sie genau wie zuvor ausgeführt wird. Versuchen Sie, die Werte des Modells zu ändern und zu sehen, wie sich auch die vom Browser geöffnete Benutzeroberfläche und URL ändern.

Aktualisieren der Notiz-Seite

Im vorigen Abschnitt wurde die Seitenansicht about an das Modell about gebunden, und jetzt werden Sie dasselbe tun und die Ansicht note an das Modell note binden. In diesem Fall wird das Modell jedoch nicht in XAML erstellt, sondern in den nächsten Schritten im CodeBehind bereitgestellt.

  1. Öffnen Sie im Fensterbereich Projektmappen-Explorer die Datei Views\NotePage.xaml.

  2. Ersetzen Sie den Inhalt durch den folgenden Ausschnitt:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:models="clr-namespace:Notes.Models"
                 x:Class="Notes.Views.NotePage"
                 Title="Note"
                 x:DataType="models:Note">
        <VerticalStackLayout Spacing="10" Margin="5">
            <Editor x:Name="TextEditor"
                    Placeholder="Enter your note"
                    Text="{Binding Text}"
                    HeightRequest="100" />
    
            <Grid ColumnDefinitions="*,*" ColumnSpacing="4">
                <Button Text="Save"
                        Clicked="SaveButton_Clicked" />
    
                <Button Grid.Column="1"
                        Text="Delete"
                        Clicked="DeleteButton_Clicked" />
            </Grid>
        </VerticalStackLayout>
    </ContentPage>
    

Sehen wir uns die geänderten Zeilen an, die im vorherigen Codeausschnitt hervorgehoben sind:

  • xmlns:models="clr-namespace:Notes.Models"

    Diese Zeile ordnet den Notes.Models .NET-Namespace dem models XML-Namespace zu.

  • x:DataType="models:Note"

    Diese Zeile weist den XAML-Compiler an, alle Bindungsausdrücke für eine höhere Laufzeitleistung zu kompilieren und die Bindungsausdrücke für den Notes.Models.Note Typ aufzulösen.

  • Text="{Binding Text}"

    Diese Zeile ändert das <Editor> Steuerelement, indem die Text Eigenschaft hinzugefügt und die Eigenschaft an die Text Eigenschaft gebunden wird.

Die Änderungen für den Code-Behind sind komplizierter als für das XAML. Der aktuelle Code lädt den Inhalt der Datei im Konstruktor und setzt ihn dann direkt auf die Eigenschaft TextEditor.Text. So sieht der aktuelle Code aus:

public NotePage()
{
    InitializeComponent();

    if (File.Exists(_fileName))
        TextEditor.Text = File.ReadAllText(_fileName);
}

Anstatt die Notiz im Konstruktor zu laden, erstellen Sie eine neue LoadNote-Methode. Mit dieser Methode wird Folgendes erreicht:

  • Akzeptieren Sie einen Dateinamenparameter.
  • Erstellen Sie ein neues Notizmodell, und legen Sie den Dateinamen fest.
  • Wenn die Datei vorhanden ist, laden Sie den Inhalt in das Modell.
  • Wenn die Datei vorhanden ist, aktualisieren Sie das Modell mit dem Erstellungsdatum der Datei.
  • Legen Sie die BindingContext-Seite auf das Modell fest.
  1. Öffnen Sie im Fensterbereich Projektmappen-Explorer die Datei Views\NotePage.xaml.cs.

  2. Fügen Sie der -Klasse die folgende Methode hinzu:

    private void LoadNote(string fileName)
    {
        Models.Note noteModel = new Models.Note();
        noteModel.Filename = fileName;
    
        if (File.Exists(fileName))
        {
            noteModel.Date = File.GetCreationTime(fileName);
            noteModel.Text = File.ReadAllText(fileName);
        }
    
        BindingContext = noteModel;
    }
    
  3. Aktualisieren Sie den Klassenkonstruktor, um LoadNote aufzurufen. Der Dateiname für die Notiz sollte ein zufällig generierter Name sein, der im lokalen Datenverzeichnis der App erstellt werden soll.

    public NotePage()
    {
        InitializeComponent();
    
        string appDataPath = FileSystem.AppDataDirectory;
        string randomFileName = $"{Path.GetRandomFileName()}.notes.txt";
    
        LoadNote(Path.Combine(appDataPath, randomFileName));
    }
    

Fügen Sie eine Ansicht und ein Modell hinzu, das alle Notizen auflistet

In diesem Teil des Tutorials wird der letzte Teil der App hinzugefügt, eine Ansicht, die alle zuvor erstellten Notizen anzeigt.

Mehrere Notizen und Navigation

Derzeit zeigt die Notiz Display Ansicht eine einzelne Notiz an. Um mehrere Notizen anzuzeigen, erstellen Sie eine neue Ansicht und ein neues Modell: AllNotes.

  1. Klicken Sie im Projektmappen-Explorer-Bereich mit der rechten Maustaste auf den Views Ordner, und wählen Sie "Neues Element> aus.
  2. Im Dialog Neues Element hinzufügen wählen Sie .NET MAUI in der Vorlagenliste auf der linken Seite des Fensters. Wählen Sie dann die Vorlage .NET MAUI ContentPage (XAML). Nennen Sie die Datei AllNotesPage.xaml und wählen Sie dann Hinzufügen aus.
  3. Klicken Sie im Projektmappen-Explorer-Bereich mit der rechten Maustaste auf den Models Ordner, und wählen Sie "Klasse> aus.
  4. Nennen Sie die Klasse AllNotes.cs und drücken Sie Hinzufügen.

Codieren des AllNotes-Modells

Das neue Modell stellt die Daten dar, die zum Anzeigen mehrerer Notizen erforderlich sind. Diese Daten sind eine Eigenschaft, die eine Sammlung von Notizen darstellt. Die Sammlung ist eine ObservableCollection, was eine spezialisierte Sammlung ist. Wenn ein Steuerelement, das mehrere Elemente auflistet, z. B. eine ListView, an eine ObservableCollection gebunden ist, arbeiten die beiden zusammen, um die Liste der Elemente automatisch mit der Sammlung zu synchronisieren. Wenn die Liste ein Element hinzufügt, wird die Sammlung aktualisiert. Wenn die Sammlung ein Element hinzufügt, wird das Steuerelement automatisch mit einem neuen Element aktualisiert.

  1. Öffnen Sie im Projektmappen-Explorer die Datei Models\AllNotes.cs.

  2. Ersetzen Sie den Code durch den folgenden Ausschnitt:

    using System.Collections.ObjectModel;
    
    namespace Notes.Models;
    
    internal class AllNotes
    {
        public ObservableCollection<Note> Notes { get; set; } = new ObservableCollection<Note>();
    
        public AllNotes() =>
            LoadNotes();
    
        public void LoadNotes()
        {
            Notes.Clear();
    
            // Get the folder where the notes are stored.
            string appDataPath = FileSystem.AppDataDirectory;
    
            // Use Linq extensions to load the *.notes.txt files.
            IEnumerable<Note> notes = Directory
    
                // Select the file names from the directory
                .EnumerateFiles(appDataPath, "*.notes.txt")
    
                // Each file name is used to create a new Note
                .Select(filename => new Note()
                {
                    Filename = filename,
                    Text = File.ReadAllText(filename),
                    Date = File.GetLastWriteTime(filename)
                })
    
                // With the final collection of notes, order them by date
                .OrderBy(note => note.Date);
    
            // Add each note into the ObservableCollection
            foreach (Note note in notes)
                Notes.Add(note);
        }
    }
    

Der vorherige Code deklariert eine Sammlung mit dem Namen Notes und verwendet die Methode LoadNotes, um Notizen von dem Gerät zu laden. Diese Methode verwendet LINQ-Erweiterungen zum Laden, Umwandeln und Sortieren der Daten in die Notes-Sammlung.

Gestalten der AllNotes-Seite

Als Nächstes muss die Ansicht so gestaltet werden, dass sie das AllNotes-Modell unterstützt.

  1. Öffnen Sie im Bereich Projektmappen-Explorer die Datei Views\AllNotesPage.xaml.

  2. Ersetzen Sie den Code durch das folgende Markup:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:models="clr-namespace:Notes.Models"
                 x:Class="Notes.Views.AllNotesPage"
                 Title="Your Notes"
                 x:DataType="models:AllNotes">
        <!-- Add an item to the toolbar -->
        <ContentPage.ToolbarItems>
            <ToolbarItem Text="Add" Clicked="Add_Clicked" IconImageSource="{FontImage Glyph='+', Color=Black, Size=22}" />
        </ContentPage.ToolbarItems>
    
        <!-- Display notes in a list -->
        <CollectionView x:Name="notesCollection"
                            ItemsSource="{Binding Notes}"
                            Margin="20"
                            SelectionMode="Single"
                            SelectionChanged="notesCollection_SelectionChanged">
    
            <!-- Designate how the collection of items are laid out -->
            <CollectionView.ItemsLayout>
                <LinearItemsLayout Orientation="Vertical" ItemSpacing="10" />
            </CollectionView.ItemsLayout>
    
            <!-- Define the appearance of each item in the list -->
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="models:Note">
                    <StackLayout>
                        <Label Text="{Binding Text}" FontSize="22"/>
                        <Label Text="{Binding Date}" FontSize="14" TextColor="Silver"/>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </ContentPage>
    

Im vorherigen XAML-Code werden einige neue Konzepte vorgestellt:

  • Die ContentPage.ToolbarItems-Eigenschaft enthält ein ToolbarItem. Die hier definierten Schaltflächen werden in der Regel am oberen Rand der App entlang des Seitentitels angezeigt. Je nach Plattform kann es sich jedoch in einer anderen Position befinden. Wenn eine dieser Schaltflächen gedrückt wird, wird das Ereignis Clicked ausgelöst, genau wie bei einer normalen Schaltfläche.

    Die Eigenschaft ToolbarItem.IconImageSource legt das Symbol fest, das auf der Schaltfläche angezeigt werden soll. Das Symbol kann eine beliebige vom Projekt definierte Bildressource sein, in diesem Beispiel wird jedoch eine FontImage verwendet. Eine FontImage kann eine einzelne Glyphe aus einer Schriftart als Bild verwenden.

  • Das CollectionView-Steuerelement zeigt eine Auflistung von Elementen an und ist in diesem Fall an die Eigenschaft des Notes-Modells gebunden. Die Art und Weise, wie jedes Element von der Sammlungsansicht dargestellt wird, wird durch die Eigenschaften CollectionView.ItemsLayout und CollectionView.ItemTemplate festgelegt.

    Für jedes Element in der Sammlung erzeugt die CollectionView.ItemTemplate die angegebene XAML. Der BindingContext dieses XAML-Codes wird selbst zum Sammlungselement, in diesem Fall jede einzelne Notiz. Die Vorlage für die Notiz verwendet zwei Beschriftungen, die an die Eigenschaften Text und Date der Notiz gebunden sind.

  • Die CollectionView behandelt das Ereignis SelectionChanged, das ausgelöst wird, wenn ein Element in der Sammlungsansicht ausgewählt wird.

Der CodeBehind für die Ansicht muss geschrieben werden, um die Notizen zu laden und die Ereignisse zu behandeln.

  1. Öffnen Sie im Bereich Projektmappen-Explorer die Datei Views/AllNotesPage.xaml.cs.

  2. Ersetzen Sie den Code durch den folgenden Ausschnitt:

    namespace Notes.Views;
    
    public partial class AllNotesPage : ContentPage
    {
        public AllNotesPage()
        {
            InitializeComponent();
    
            BindingContext = new Models.AllNotes();
        }
    
        protected override void OnAppearing()
        {
            ((Models.AllNotes)BindingContext).LoadNotes();
        }
    
        private async void Add_Clicked(object sender, EventArgs e)
        {
            await Shell.Current.GoToAsync(nameof(NotePage));
        }
    
        private async void notesCollection_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.CurrentSelection.Count != 0)
            {
                // Get the note model
                var note = (Models.Note)e.CurrentSelection[0];
    
                // Should navigate to "NotePage?ItemId=path\on\device\XYZ.notes.txt"
                await Shell.Current.GoToAsync($"{nameof(NotePage)}?{nameof(NotePage.ItemId)}={note.Filename}");
    
                // Unselect the UI
                notesCollection.SelectedItem = null;
            }
        }
    }
    

Dieser Code verwendet den Konstruktor, um die BindingContext der Seite auf das Modell festzulegen.

Die OnAppearing-Methode wird von der Basisklasse außer Kraft gesetzt. Diese Methode wird automatisch aufgerufen, wenn die Seite angezeigt wird, z. B. wenn die Seite navigiert wird. Der Code hier weist das Modell an, die Notizen zu laden. Da CollectionView in der AllNotes-Ansicht an die Eigenschaft des Notes AllNotes-Modells gebunden ist, welche ein ObservableCollection ist, wird CollectionView bei jedem Laden der Notizen automatisch aktualisiert.

Der Add_Clicked-Handler führt ein weiteres neues Konzept ein, die Navigation. Da die App die .NET MAUI Shell verwendet, können Sie durch den Aufruf der Shell.Current.GoToAsync-Methode zu den Seiten navigieren. Beachten Sie, dass der Handler mit dem Schlüsselwort async deklariert wird, was die Verwendung des Schlüsselworts await beim Navigieren ermöglicht. Dieser Handler navigiert zu der NotePage.

Der letzte Codeabschnitt im vorherigen Codeausschnitt ist der notesCollection_SelectionChanged-Handler. Diese Methode verwendet das aktuell ausgewählte Element, ein Note-Modell und verwendet seine Informationen, um zum NotePage-Element zu navigieren. GoToAsync verwendet eine URI-Zeichenfolge für die Navigation. In diesem Fall wird eine Zeichenfolge erstellt, die einen Abfragezeichenfolgenparameter verwendet, um eine Eigenschaft auf der Zielseite festzulegen. Die interpolierte Zeichenfolge, die den URI darstellt, sieht ähnlich wie die folgende Zeichenfolge aus:

NotePage?ItemId=path\on\device\XYZ.notes.txt

Der ItemId=-Parameter wird auf den Dateinamen auf dem Gerät festgelegt, auf dem die Notiz gespeichert ist.

Visual Studio gibt möglicherweise an, dass die NotePage.ItemId Eigenschaft nicht vorhanden ist, was sie nicht tut. Der nächste Schritt besteht darin, die Note Ansicht so zu ändern, dass das Modell auf der Grundlage des von Ihnen erstellten ItemId-Parameters geladen wird.

Abfragezeichenfolge-Parameter

Die Note Ansicht muss den Abfragezeichenfolgenparameter ItemId unterstützen. Erstellen Sie ihn jetzt:

  1. Öffnen Sie im Bereich Projektmappen-Explorer die Datei Views/NotePage.xaml.cs.

  2. Fügen Sie das Attribut QueryProperty zum Schlüsselwort class hinzu und geben Sie den Namen der Anfragenzeichenfolgen-Eigenschaft und die Klasseneigenschaft an, auf die sie abgebildet wird, ItemId bzw. ItemId:

    [QueryProperty(nameof(ItemId), nameof(ItemId))]
    public partial class NotePage : ContentPage
    
  3. Fügen Sie eine string-Eigenschaft namens ItemId hinzu. Diese Eigenschaft ruft die LoadNote-Methode auf und übergibt den Wert der Eigenschaft, die wiederum der Dateiname der Notiz sein sollte:

    public string ItemId
    {
        set { LoadNote(value); }
    }
    
  4. Ersetzen Sie die Handler SaveButton_Clicked und DeleteButton_Clicked durch den folgenden Code:

    private async void SaveButton_Clicked(object sender, EventArgs e)
    {
        if (BindingContext is Models.Note note)
            File.WriteAllText(note.Filename, TextEditor.Text);
    
        await Shell.Current.GoToAsync("..");
    }
    
    private async void DeleteButton_Clicked(object sender, EventArgs e)
    {
        if (BindingContext is Models.Note note)
        {
            // Delete the file.
            if (File.Exists(note.Filename))
                File.Delete(note.Filename);
        }
    
        await Shell.Current.GoToAsync("..");
    }
    

    Die Schaltflächen sind jetzt async. Nachdem sie gedrückt wurden, navigiert die Seite mit einem URI von .. zurück zur vorherigen Seite.

  5. Löschen Sie die Variable _fileName vom Anfang des Codes, da sie von der Klasse nicht mehr verwendet wird.

Ändern der visuellen Struktur der App

Die AppShell lädt immer noch die einzelne Notizseite, sie muss aber stattdessen die Ansicht AllPages laden. Öffnen Sie die Datei AppShell.xaml und ändern Sie den ersten ShellContent-Eintrag, sodass er auf AllNotesPage anstelle von NotePage verweist:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="Notes.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:views="clr-namespace:Notes.Views"
    Shell.FlyoutBehavior="Disabled">

    <TabBar>
        <ShellContent
            Title="Notes"
            ContentTemplate="{DataTemplate views:AllNotesPage}"
            Icon="{OnPlatform 'icon_notes.png', iOS='icon_notes_ios.png', MacCatalyst='icon_notes_ios.png'}" />

        <ShellContent
            Title="About"
            ContentTemplate="{DataTemplate views:AboutPage}"
            Icon="{OnPlatform 'icon_about.png', iOS='icon_about_ios.png', MacCatalyst='icon_about_ios.png'}" />
    </TabBar>

</Shell>

Wenn Sie die App jetzt starten, werden Sie feststellen, dass sie abstürzt, wenn Sie die Schaltfläche Hinzufügen drücken, und sich beschwert, dass sie nicht zu NotesPage navigieren kann. Jede Seite, zu der von einer anderen Seite navigiert werden kann, muss beim Navigationssystem registriert werden. Die Seiten AllNotesPage und AboutPage werden automatisch im Navigationssystem registriert, indem sie in der TabBar angegeben werden.

Registrieren Sie die NotesPage im Navigationssystem:

  1. Öffnen Sie im Projektmappen-Explorer die Datei AppShell.xaml.cs.

  2. Fügen Sie dem Konstruktor eine Zeile hinzu, die die Navigationsroute registriert:

    namespace Notes;
    
    public partial class AppShell : Shell
    {
        public AppShell()
        {
            InitializeComponent();
    
            Routing.RegisterRoute(nameof(Views.NotePage), typeof(Views.NotePage));
        }
    }
    

Die Methode Routing.RegisterRoute akzeptiert zwei Parameter:

  • Der erste Parameter ist der Zeichenfolgename des zu registrierenden URI, in diesem Fall ist der aufgelöste Name "NotePage".
  • Der zweite Parameter ist der Typ der Seite, die geladen werden soll, wenn zu "NotePage" navigiert wird.

Sie können Ihre App jetzt ausführen. Versuchen Sie, neue Notizen hinzuzufügen, zwischen Notizen zu navigieren und Notizen zu löschen.

Erkunden Sie den Code. Erkunden Sie den Code für dieses Tutorial.. Wenn Sie eine Kopie des fertigen Projekts herunterladen möchten, um Ihren Code damit zu vergleichen, laden Sie dieses Projekt herunter.

Sie haben das Lernprogramm zum Erstellen einer .NET MAUI-App abgeschlossen!

Nächste Schritte

Im nächsten Lernprogramm erfahren Sie, wie Sie Model-view-viewmodel (MVVM)-Muster in Ihrem Projekt implementieren.

Die folgenden Links enthalten weitere Informationen zu einigen der Konzepte, die Sie in diesem Lernprogramm gelernt haben: