Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här delen av självstudien beskriver begreppen datavyer och modeller.
I föregående steg i självstudien lade du till en ny sida i projektet som låter användaren spara, redigera eller ta bort en enda anteckning. Men eftersom appen behöver hantera mer än en anteckning måste du lägga till en annan sida som visar alla anteckningar (anropa den AllNotesPage). På den här sidan ska användaren välja en anteckning som ska öppnas på redigeringssidan så att de kan visa, redigera eller ta bort den. Det bör också låta användaren skapa en ny anteckning.
För att göra detta AllNotesPage måste ha en samling anteckningar och ett sätt att visa samlingen. Det är här appen får problem eftersom anteckningsdata är nära bundna till NotePage filen. I AllNotesPagevill du bara visa alla anteckningar i en lista eller annan samlingsvy, med information om varje anteckning, till exempel det datum då den skapades och en förhandsgranskning av texten. Eftersom anteckningstexten är nära bunden till TextBox kontrollen finns det inget sätt att göra detta.
Innan du lägger till en sida för att visa alla anteckningar ska vi göra några ändringar för att separera anteckningsdata från anteckningspresentationen.
Vyer och modeller
Vanligtvis har en WinUI-app minst ett visningslager och ett datalager.
Visningslagret definierar användargränssnittet med XAML-markering. Pålägget innehåller databindningsuttryck (till exempel x:Bind) som definierar anslutningen mellan specifika gränssnittskomponenter och datamedlemmar. Kod bakom filer används ibland som en del av visningslagret för att innehålla ytterligare kod som behövs för att anpassa eller ändra användargränssnittet, eller för att extrahera data från händelsehanterarargument innan du anropar en metod som utför arbetet med data.
Datalagret, eller modellen, definierar de typer som representerar dina appdata och relaterad logik. Det här lagret är oberoende av visningslagret och du kan skapa flera olika vyer som interagerar med data.
NotePage För närvarande representerar en vy av data (anteckningstexten). Men när data har lästs in i appen från systemfilen finns de Text bara i egenskapen TextBox i i NotePage. Den representeras inte i appen på ett sätt som gör att du kan presentera data på olika sätt eller på olika platser. Det innebär att appen inte har något datalager. Nu ska du strukturera om projektet för att skapa dataskiktet.
Avgränsa vyn och modellen
Tips/Råd
Du kan ladda ned eller visa koden för den här självstudien från GitHub-lagringsplatsen. Om du vill se koden som den är i det här steget kan du läsa den här incheckningssidan: anteckningssida – visningsmodell.
Omstrukturera den befintliga koden för att separera modellen från vyn. Följande steg ordnar koden så att vyer och modeller definieras separat från varandra.
Högerklicka på projektet i WinUINotes och välj Lägg till>ny mapp. Ge mappen namnet Models.
Högerklicka på WinUINotes projektet igen och välj Lägg till>ny mapp. Ge mappen namnet Views.
Leta upp objektet NotePage.xaml och dra det till Views mappen. Filen NotePage.xaml.cs bör flyttas med den.
Anmärkning
När du flyttar en fil uppmanar Visual Studio dig vanligtvis med en varning om hur flyttåtgärden kan ta lång tid. Detta bör inte vara ett problem här, tryck på OK om du ser den här varningen.
Visual Studio kan också fråga dig om du vill justera namnområdet för den flyttade filen. Välj Nej. Du ändrar namnområdet i nästa steg.
Uppdatera visningsnamnområdet
Nu när vyn har flyttats till Views mappen måste du uppdatera namnrymderna så att de matchar. Namnområdet för XAML- och kod bakom-filerna på sidorna är inställt på WinUINotes. Detta måste uppdateras till WinUINotes.Views.
I fönstret Solution Explorer expanderar du NotePage.xaml för att visa filen bakom koden.
Dubbelklicka på objektet NotePage.xaml.cs för att öppna kodredigeraren om det inte redan är öppet. Ändra namnområdet till
WinUINotes.Views:namespace WinUINotes.ViewsDubbelklicka på objektet NotePage.xaml för att öppna XAML-redigeraren om den inte redan är öppen. Det gamla namnområdet refereras via attributet
x:Class, som definierar vilken klasstyp som är kod bakom för XAML. Den här posten är inte bara namnområdet, utan namnområdet med typen . Ändra värdet förx:ClasstillWinUINotes.Views.NotePage:x:Class="WinUINotes.Views.NotePage"
Åtgärda namnområdesreferensen i MainWindow
I föregående steg skapade du anteckningssidan och uppdaterade MainWindow.xaml den för att navigera till den. Kom ihåg att den mappades med namnområdesmappningen local: . Det är vanligt att mappa namnet local till projektets rotnamnområde, och Visual Studio-projektmallen gör redan detta åt dig (xmlns:local="using:WinUINotes"). Nu när sidan har flyttats till ett nytt namnområde är typmappningen i XAML nu ogiltig.
Som tur är kan du lägga till egna namnområdesmappningar efter behov. Du måste göra detta för att komma åt objekt i olika mappar som du skapar i projektet. Det nya XAML-namnområdet mappas till namnområdet WinUINotes.Viewsför , så ge det viewsnamnet . Deklarationen bör se ut som följande attribut: xmlns:views="using:WinUINotes.Views".
I fönstret Solution Explorer dubbelklickar du på posten MainWindow.xaml för att öppna den i XAML-redigeraren.
Lägg till den här nya namnområdesmappningen på raden under mappningen för
local:xmlns:views="using:WinUINotes.Views"XAML-namnområdet
localanvändes för att angeFrame.SourcePageTypeegenskapen, så ändra den tillviewsdär. Din XAML bör nu se ut så här:<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>Skapa och kör appen. Appen ska köras utan kompilatorfel och allt bör fortfarande fungera som tidigare.
Definiera modellen
För närvarande är modellen (data) inbäddad i anteckningsvyn. Du skapar en ny klass som representerar en anteckningssidas data:
I fönstret Solution Explorer högerklickar du på mappen Models och väljer Lägg till>klass....
Ge klassen Note.cs namnet och tryck på Lägg till. Filen Note.cs öppnas i kodredigeraren.
Ersätt koden i filen med den Note.cs här koden, vilket gör klassen
publicoch lägger till egenskaper och metoder för att hantera en anteckning: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(); } } } }Spara filen.
Du kommer att märka att den här koden liknar koden i NotePage.xaml.cs, med några ändringar och tillägg.
Filenameoch Text har ändrats till egenskaper och en ny public egenskap har lagts tillDate.
Koden för att spara och ta bort filerna har placerats i public metoder. Den är mestadels identisk med den kod som du använde i knapphändelsehanterarna Click i NotePage, men extra kod för att uppdatera vyn när filen har tagits bort har tagits bort. Det behövs inte här eftersom du använder databindning för att hålla modellen och vyn synkroniserad.
Dessa asynkrona metodsignaturer returnerar Aktivitet i stället för void. Klassen Task representerar en enda asynkron åtgärd som inte returnerar ett värde. Om inte metodsignaturen kräver void, vilket är fallet för Click händelsehanterarna, async ska metoderna returnera en Task.
Du kommer inte heller att behålla en referens till StorageFile den som innehåller anteckningen längre. Du försöker bara hämta filen när du behöver den för att spara eller ta bort den.
I NotePageanvände du en platshållare för filnamnet: note.txt. Nu när appen har stöd för mer än en anteckning måste filnamnen för sparade anteckningar vara olika och unika. Det gör du genom att Filename ange egenskapen i konstruktorn. Du kan använda metoden DateTime.ToBinary för att skapa en del av filnamnet baserat på aktuell tid och göra filnamnen unika. Det genererade filnamnet ser ut så här: notes-8584626598945870392.txt.
Uppdatera anteckningssidan
Nu kan du uppdatera NotePage vyn för att använda Note datamodellen och ta bort kod som har flyttats till Note modellen.
Öppna filen Views\NotePage.xaml.cs om den inte redan är öppen i redigeraren.
Efter den sista
usinginstruktionen överst på sidan lägger du till en nyusinginstruktion för att ge din kod åtkomst till klasserna iModelsmappen och namnområdet.using WinUINotes.Models;Ta bort dessa rader från klassen:
private StorageFolder storageFolder = ApplicationData.Current.LocalFolder; private StorageFile? noteFile = null; private string fileName = "note.txt";Lägg i stället till ett
Noteobjekt med namnetnoteModeli deras ställe. Detta representerar de anteckningsdata somNotePageger en vy över.private Note? noteModel;Du behöver
NotePage_Loadedinte heller händelsehanteraren längre. Du kommer inte att läsa text direkt från textfilen till textrutan. I stället kommer anteckningstexten att läsas in iNoteobjekt. Du lägger till koden för detta när du lägger tillAllNotesPagei ett senare steg. Ta bort dessa rader.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); } }Ersätt koden i
SaveButton_Clickmetoden med följande:if (noteModel is not null) { await noteModel.SaveAsync(); }Ersätt koden i
DeleteButton_Clickmetoden med följande:if (noteModel is not null) { await noteModel.DeleteAsync(); }
Nu kan du uppdatera XAML-filen så att den Note använder modellen. Tidigare läste du texten direkt från textfilen till TextBox.Text egenskapen i filen bakom koden. Nu använder du databindning för egenskapen Text .
Öppna filen Views\NotePage.xaml om den inte redan är öppen i redigeraren.
Lägg till ett
Textattribut iTextBoxkontrollen. Binda denTexttill egenskapennoteModel:Text="{x:Bind noteModel.Text, Mode=TwoWay}".Uppdatera för
Headeratt binda tillDateegenskapennoteModel: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"/>
Databindning är ett sätt för appens användargränssnitt att visa data och, om så önskas, förbli synkroniserad med dessa data. Inställningen Mode=TwoWay för bindningen innebär att TextBox.Text egenskaperna och noteModel.Text synkroniseras automatiskt. När texten uppdateras i TextBoxåterspeglas ändringarna i Text egenskapen noteModelför , och om noteModel.Text ändras återspeglas uppdateringarna TextBoxi .
Egenskapen Header använder standardvärdet ModeOneTime eftersom noteModel.Date egenskapen inte ändras när filen har skapats. Den här koden visar också en kraftfull funktion x:Bind som kallas funktionsbindning, vilket gör att du kan använda en funktion som ToString ett steg i bindningssökvägen.
Viktigt!
Det är viktigt att välja rätt BindingMode; annars kanske databindningen inte fungerar som förväntat. (Ett vanligt misstag med {x:Bind} är att glömma att ändra standardvärdet BindingMode när OneWay eller TwoWay behövs.)
| Namn | Description |
|---|---|
OneTime |
Uppdaterar endast målegenskapen när bindningen skapas. Standard för {x:Bind}. |
OneWay |
Uppdaterar målegenskapen när bindningen skapas. Ändringar i källobjektet kan också spridas till målet. Standard för {Binding}. |
TwoWay |
Uppdaterar antingen målet eller källobjektet när något av ändringarna ändras. När bindningen skapas uppdateras målegenskapen från källan. |
Databindning stöder separation av dina data och användargränssnitt, och det resulterar i en enklare konceptuell modell samt bättre läsbarhet, testbarhet och underhåll av din app.
I WinUI finns det två typer av bindningar som du kan välja mellan:
- Påläggstillägget
{x:Bind}bearbetas vid kompileringstillfället. Några av dess fördelar är förbättrad prestanda och kompileringstidsvalidering av dina bindningsuttryck. Det rekommenderas för bindning i WinUI-appar. -
{Binding}Markeringstillägget bearbetas vid körning och använder allmän körningsobjektgranskning.
Läs mer i dokumenten:
Databindning och MVVM
Model-View-ViewModel (MVVM) är ett arkitekturdesignmönster för användargränssnitt för avkoppling av användargränssnitt och icke-UI-kod som är populär bland .NET-utvecklare. Du kommer förmodligen att se och höra det nämnas när du lär dig mer om att skapa WinUI-appar. Att separera vyer och modeller, som du har gjort här, är det första steget mot en fullständig MVVM-implementering av appen, men det är så långt du kommer att gå i den här självstudien.
Anmärkning
Vi har använt termen "modell" för att referera till datamodellen i den här självstudien, men det är viktigt att observera att den här modellen är mer anpassad till ViewModel i en fullständig MVVM-implementering, samtidigt som vi införlivar aspekter av modellen.
Mer information om MVVM finns i följande resurser:
Windows developer