Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Teil des Lernprogramms werden die Konzepte von Datenansichten und -modellen vorgestellt.
In den vorherigen Schritten des Lernprogramms haben Sie dem Projekt eine neue Seite hinzugefügt, mit der der Benutzer eine einzelne Notiz speichern, bearbeiten oder löschen kann. Da die App jedoch mehrere Notizen verarbeiten muss, müssen Sie eine weitere Seite hinzufügen, auf der alle Notizen angezeigt werden (aufrufen AllNotesPage). Auf dieser Seite können Benutzer eine Notiz auswählen, die auf der Editorseite geöffnet werden soll, damit sie sie anzeigen, bearbeiten oder löschen können. Außerdem sollte der Benutzer eine neue Notiz erstellen lassen.
AllNotesPage Dazu muss eine Sammlung von Notizen und eine Möglichkeit zum Anzeigen der Sammlung vorhanden sein. In diesem Fall tritt die App in Schwierigkeiten auf, da die Notizdaten eng an die NotePage Datei gebunden sind. In AllNotesPage, Sie möchten nur alle Notizen in einer Liste oder einer anderen Sammlungsansicht mit Informationen zu jeder Notiz anzeigen, z. B. das Erstellungsdatum und eine Vorschau des Texts. Da der Notiztext eng an das TextBox Steuerelement gebunden ist, gibt es keine Möglichkeit, dies zu tun.
Bevor Sie eine Seite hinzufügen, um alle Notizen anzuzeigen, nehmen wir einige Änderungen vor, um die Notizdaten von der Notizenpräsentation zu trennen.
Ansichten und Modelle
In der Regel verfügt eine WinUI-App über mindestens eine Ansichtsebene und eine Datenebene.
Die Ansichtsebene definiert die Benutzeroberfläche mithilfe von XAML-Markup. Das Markup enthält Datenbindungsausdrücke (z. B. x:Bind), die die Verbindung zwischen bestimmten UI-Komponenten und Datenelementen definieren. CodeBehind-Dateien werden manchmal als Teil der Ansichtsebene verwendet, um zusätzlichen Code zu enthalten, der zum Anpassen oder Bearbeiten der Benutzeroberfläche erforderlich ist, oder um Daten aus Ereignishandlerargumenten zu extrahieren, bevor eine Methode aufgerufen wird, die die Arbeit an den Daten ausführt.
Die Datenebene oder das Modell definiert die Typen, die Ihre App-Daten und zugehörige Logik darstellen. Diese Ebene ist unabhängig von der Ansichtsebene, und Sie können mehrere verschiedene Ansichten erstellen, die mit den Daten interagieren.
Derzeit stellt die NotePage Darstellung eine Datenansicht (den Notiztext) dar. Nachdem die Daten jedoch aus der Systemdatei in die App gelesen wurden, ist sie nur in der Text Eigenschaft des TextBox Ins NotePagevorhanden. Es wird nicht in der App auf eine Weise dargestellt, mit der Sie die Daten auf unterschiedliche Weise oder an unterschiedlichen Stellen darstellen können. d. h. die App verfügt nicht über eine Datenebene. Sie strukturieren das Projekt jetzt neu, um die Datenschicht zu erstellen.
Trennen der Ansicht und des Modells
Tipp
Sie können den Code für dieses Lernprogramm aus dem GitHub-Repository herunterladen oder anzeigen. Um den Code wie in diesem Schritt anzuzeigen, lesen Sie diesen Commit: Notizseite – Ansichtsmodell.
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.
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das WinUINotes Projekt, und wählen Sie"Neuen Ordner>" aus. Geben Sie dem Ordner den Namen Models.
Klicken Sie erneut mit der rechten Maustaste auf das WinUINotes Projekt, und wählen Sie "Neuen Ordner>" aus. Geben Sie dem Ordner den Namen Views.
Suchen Sie das NotePage.xaml Element, und ziehen Sie es in den Views Ordner. Die NotePage.xaml.cs Datei sollte mit der Datei verschoben werden.
Hinweis
Wenn Sie eine Datei verschieben, fordert Visual Studio Sie in der Regel mit einer Warnung dazu auf, dass der Vorgang des Verschiebens lange dauern kann. Dies sollte hier kein Problem sein, drücken Sie OK, wenn Sie diese Warnung sehen.
Visual Studio fragt Sie möglicherweise auch, ob Sie den Namespace der verschobenen Datei anpassen möchten. Wählen Sie "Nein" aus. Sie ändern den Namespace in den nächsten Schritten.
Aktualisieren des Namespace der Ansicht
Nachdem die Ansicht in den Views Ordner verschoben wurde, müssen Sie die Namespaces entsprechend aktualisieren. Der Namespace für die XAML- und Code-Behind-Dateien der Seiten ist auf WinUINotes festgelegt. Das muss auf WinUINotes.Views aktualisiert werden.
Erweitern Sie im NotePage.xaml, um die CodeBehind-Datei anzuzeigen.
Doppelklicken Sie auf das NotePage.xaml.cs Element, um den Code-Editor zu öffnen, wenn es noch nicht geöffnet ist. Ändern Sie den Namespace in
WinUINotes.Views.namespace WinUINotes.ViewsDoppelklicken Sie auf das NotePage.xaml Element, um den XAML-Editor zu öffnen, wenn es noch nicht geöffnet ist. 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 vonx:ClasszuWinUINotes.Views.NotePage:x:Class="WinUINotes.Views.NotePage"
Beheben des Namespaceverweises in MainWindow
Im vorherigen Schritt haben Sie die Notizseite erstellt und aktualisiert MainWindow.xaml , um dorthin zu navigieren. Denken Sie daran, dass sie mit der local: Namespacezuordnung zugeordnet wurde. Es ist üblich, den Namen local dem Stammnamespace Ihres Projekts zuzuordnen, und die Visual Studio-Projektvorlage macht dies bereits für Sie (xmlns:local="using:WinUINotes"). Nachdem die Seite in einen neuen Namespace verschoben wurde, ist die Typzuordnung im XAML-Code jetzt ungültig.
Glücklicherweise können Sie bei Bedarf eigene Namespacezuordnungen hinzufügen. Dazu müssen Sie auf Elemente in verschiedenen Ordnern zugreifen, die Sie in Ihrem Projekt erstellen. Dieser neue XAML-Namespace wird dem Namespace von WinUINotes.Views, also benennen Sie ihn viewszugeordnet. Die Deklaration sollte wie das folgende Attribut aussehen: xmlns:views="using:WinUINotes.Views".
Doppelklicken Sie im Projektmappen-Explorer-Bereich auf den Eintrag "MainWindow.xaml ", um ihn im XAML-Editor zu öffnen.
Fügen Sie diese neue Namespacezuordnung in der Zeile unterhalb der Zuordnung für
local:xmlns:views="using:WinUINotes.Views"Der
localXAML-Namespace wurde verwendet, um dieFrame.SourcePageTypeEigenschaft festzulegen. Ändern Sie ihn also dortviews. Ihr XAML sollte jetzt wie folgt aussehen:<Window x:Class="WinUINotes.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:WinUINotes" xmlns:views="using:WinUINotes.Views" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="WinUI Notes"> <!-- ... Unchanged XAML not shown. --> <Frame x:Name="rootFrame" Grid.Row="1" SourcePageType="views:NotePage"/> <!-- ... Unchanged XAML not shown. --> </Window>Erstellen Sie die App und führen Sie sie aus. Die App sollte ohne Compilerfehler ausgeführt werden, und alles sollte wie zuvor funktionieren.
Definieren des Modells
Derzeit wird das Modell (die Daten) in die Notizenansicht eingebettet. Sie erstellen eine neue Klasse, um die Daten einer Notizseite darzustellen:
Klicken Sie im Bereich Projektmappen-Explorer mit der rechten Maustaste auf den Ordner Models und wählen Sie Hinzufügen>Klasse....
Benennen Sie die Klasse Note.cs , und drücken Sie "Hinzufügen". Die Note.cs Datei wird im Code-Editor geöffnet.
Ersetzen Sie den Code in der Note.cs Datei durch diesen Code, wodurch die Klasse
publicerstellt und Eigenschaften und Methoden zum Behandeln einer Notiz hinzugefügt werden:using System; using System.Threading.Tasks; using Windows.Storage; namespace WinUINotes.Models { public class Note { private StorageFolder storageFolder = ApplicationData.Current.LocalFolder; public string Filename { get; set; } = string.Empty; public string Text { get; set; } = string.Empty; public DateTime Date { get; set; } = DateTime.Now; public Note() { Filename = "notes" + DateTime.Now.ToBinary().ToString() + ".txt"; } public async Task SaveAsync() { // Save the note to a file. StorageFile noteFile = (StorageFile)await storageFolder.TryGetItemAsync(Filename); if (noteFile is null) { noteFile = await storageFolder.CreateFileAsync(Filename, CreationCollisionOption.ReplaceExisting); } await FileIO.WriteTextAsync(noteFile, Text); } public async Task DeleteAsync() { // Delete the note from the file system. StorageFile noteFile = (StorageFile)await storageFolder.TryGetItemAsync(Filename); if (noteFile is not null) { await noteFile.DeleteAsync(); } } } }Speichern Sie die Datei.
Sie werden feststellen, dass dieser Code mit einigen Änderungen und Ergänzungen dem Code NotePage.xaml.cssehr ähnlich ist.
Filename und Text wurden in public Eigenschaften geändert, und eine neue Date Eigenschaft wurde hinzugefügt.
Der Code zum Speichern und Löschen der Dateien wurde in public Methoden eingefügt. Es ist hauptsächlich identisch mit dem Code, den Sie in den Schaltflächenereignishandlern ClickNotePageverwendet haben, aber zusätzlicher Code zum Aktualisieren der Ansicht nach dem Löschen der Datei wurde entfernt. Es ist hier nicht erforderlich, da Sie die Datenbindung verwenden, um das Modell und die Ansicht zu synchronisieren.
Diese asynchronen Methodensignaturen geben Task anstelle von void. Die Task Klasse stellt einen einzelnen asynchronen Vorgang dar, der keinen Wert zurückgibt. Es sei denn, die Methodensignatur erfordert void, wie bei den Click Ereignishandlern der Fall ist, async sollten Methoden eine .Task
Außerdem behalten Sie keinen Verweis auf die StorageFile Notiz mehr bei. Sie versuchen einfach, die Datei abzurufen, wenn sie zum Speichern oder Löschen benötigt wird.
In NotePage, Sie haben einen Platzhalter für den Dateinamen verwendet: note.txt. Da die App nun mehr als eine Notiz unterstützt, müssen Dateinamen für gespeicherte Notizen unterschiedlich und eindeutig sein. Legen Sie dazu die Filename Eigenschaft im Konstruktor fest. Sie können die DateTime.ToBinary-Methode verwenden, um einen Teil des Dateinamens basierend auf der aktuellen Uhrzeit zu erstellen und die Dateinamen eindeutig zu machen. Der generierte Dateiname sieht wie folgt aus: notes-8584626598945870392.txt.
Aktualisieren der Notizseite
Jetzt können Sie die NotePage Ansicht aktualisieren, um das Note Datenmodell zu verwenden und Code zu löschen, der in das Note Modell verschoben wurde.
Öffnen Sie die Datei "Views\NotePage.xaml.cs ", wenn sie noch nicht im Editor geöffnet ist.
Fügen Sie nach der letzten
usingAnweisung oben auf der Seite eine neueusingAnweisung hinzu, um Ihrem Code Zugriff auf die Klassen imModelsOrdner und Namespace zu gewähren.using WinUINotes.Models;Löschen Sie diese Zeilen aus der Klasse:
private StorageFolder storageFolder = ApplicationData.Current.LocalFolder; private StorageFile? noteFile = null; private string fileName = "note.txt";Fügen Sie stattdessen ein
NoteObjekt hinzu, das an ihrer Stelle benannt istnoteModel. Dies stellt die Notizdaten dar, dieNotePageeine Ansicht enthalten.private Note? noteModel;Außerdem benötigen Sie den
NotePage_LoadedEreignishandler nicht mehr. Text wird nicht direkt aus der Textdatei in das TextBox-Element gelesen. Stattdessen wird der Notiztext inNoteObjekte gelesen. Sie fügen den Code dafür hinzu, wenn Sie denAllNotesPageIn einem späteren Schritt hinzufügen. Löschen Sie diese Zeilen.Loaded += NotePage_Loaded; ... private async void NotePage_Loaded(object sender, RoutedEventArgs e) { noteFile = (StorageFile)await storageFolder.TryGetItemAsync(fileName); if (noteFile is not null) { NoteEditor.Text = await FileIO.ReadTextAsync(noteFile); } }Ersetzen Sie den Code in der
SaveButton_ClickMethode durch folgendes:if (noteModel is not null) { await noteModel.SaveAsync(); }Ersetzen Sie den Code in der
DeleteButton_ClickMethode durch folgendes:if (noteModel is not null) { await noteModel.DeleteAsync(); }
Jetzt können Sie die XAML-Datei aktualisieren, um das Note Modell zu verwenden. Zuvor lesen Sie den Text direkt aus der Textdatei in die TextBox.Text Eigenschaft in der CodeBehind-Datei. Jetzt verwenden Sie die Datenbindung für die Text Eigenschaft.
Öffnen Sie die Datei "Views\NotePage.xaml ", wenn sie noch nicht im Editor geöffnet ist.
Fügen Sie dem
TextSteuerelement einTextBoxAttribut hinzu. Binden Sie es an dieTextEigenschaft vonnoteModel:Text="{x:Bind noteModel.Text, Mode=TwoWay}".Aktualisieren Sie die
HeaderBindung an dieDateEigenschaft vonnoteModel:Header="{x:Bind noteModel.Date.ToString()}".<TextBox x:Name="NoteEditor" <!-- ↓ Add this line. ↓ --> Text="{x:Bind noteModel.Text, Mode=TwoWay}" AcceptsReturn="True" TextWrapping="Wrap" PlaceholderText="Enter your note" <!-- ↓ Update this line. ↓ --> Header="{x:Bind noteModel.Date.ToString()}" ScrollViewer.VerticalScrollBarVisibility="Auto" Width="400" Grid.Column="1"/>
Die Datenbindung ist eine Möglichkeit für die Benutzeroberfläche Ihrer App zum Anzeigen von Daten und optional zum Synchronisieren mit diesen Daten. Die Mode=TwoWay Einstellung für die Bindung bedeutet, dass die Eigenschaften und TextBox.Text die noteModel.Text Eigenschaften automatisch synchronisiert werden. Wenn der Text in der TextBoxAktualisiert wird, werden die Änderungen in der Text Eigenschaft des noteModel, und wenn noteModel.Text geändert, die Aktualisierungen in der TextBox.
Die Header Eigenschaft verwendet den Standardwert Mode , OneTime da sich die noteModel.Date Eigenschaft nach dem Erstellen der Datei nicht ändert. Dieser Code veranschaulicht auch ein leistungsfähiges Feature der x:Bind aufgerufenen Funktionsbindung, mit dem Sie eine Funktion wie ToString einen Schritt im Bindungspfad verwenden können.
Von Bedeutung
Es ist wichtig, den richtigen BindingMode auszuwählen; andernfalls funktioniert die Datenbindung möglicherweise nicht wie erwartet. (Ein häufiger Fehler {x:Bind} besteht darin, zu vergessen, den Standardwert BindingMode bei OneWay Bedarf TwoWay zu ändern.)
| Name | Description |
|---|---|
OneTime |
Aktualisiert die Zieleigenschaft nur, wenn die Bindung erstellt wird. Standard für {x:Bind}. |
OneWay |
Aktualisiert die Zieleigenschaft, wenn die Bindung erstellt wird. Änderungen am Quellobjekt können auch an das Ziel weitergegeben werden. Standard für {Binding}. |
TwoWay |
Aktualisiert entweder das Ziel oder das Quellobjekt, wenn sich eine der Änderungen ändert. Wenn die Bindung erstellt wird, wird die Zieleigenschaft aus der Quelle aktualisiert. |
Die Datenbindung unterstützt die Trennung Ihrer Daten und der Benutzeroberfläche und führt zu einem einfacheren konzeptuellen Modell sowie zu einer besseren Lesbarkeit, Testbarkeit und Wartung Ihrer App.
In WinUI gibt es zwei Arten von Bindung, aus denen Sie wählen können:
- Die
{x:Bind}Markuperweiterung wird zur Kompilierung verarbeitet. Einige seiner Vorteile sind verbesserte Leistung und Kompilierungszeitüberprüfung Ihrer Bindungsausdrücke. Es wird empfohlen, die Bindung in WinUI-Apps zu binden. - Die
{Binding}Markuperweiterung wird zur Laufzeit verarbeitet und verwendet eine allgemeine Laufzeitobjektüberprüfung.
Weitere Informationen finden Sie in den Dokumenten:
Datenbindung und MVVM
Model-View-ViewModel (MVVM) ist ein Entwurfsmuster für die Ui-Architektur zum Entkoppeln von UI- und Nicht-UI-Code, der für .NET-Entwickler beliebt ist. Sie werden es wahrscheinlich sehen und hören, während Sie mehr über das Erstellen von WinUI-Apps erfahren. Das Trennen der Ansichten und Modelle, wie Sie es hier getan haben, ist der erste Schritt zu einer vollständigen MVVM-Implementierung der App, aber es ist so weit, wie Sie in diesem Lernprogramm gehen.
Hinweis
Wir haben den Begriff "Modell" verwendet, um auf das Datenmodell in diesem Lernprogramm zu verweisen, aber es ist wichtig zu beachten, dass dieses Modell enger mit dem ViewModel in einer vollständigen MVVM-Implementierung ausgerichtet ist und gleichzeitig Aspekte des Modells enthält.
Weitere Informationen zu MVVM finden Sie in den folgenden Ressourcen:
Windows developer