Megosztás:


Nézet és modell hozzáadása a jegyzethez

Az oktatóanyag ezen része bemutatja az adatnézetek és modellek fogalmait.

Az oktatóanyag előző lépéseiben hozzáadott egy új lapot a projekthez, amellyel a felhasználó egyetlen megjegyzést menthet, szerkeszthet vagy törölhet. Mivel azonban az alkalmazásnak több megjegyzést kell kezelnie, hozzá kell adnia egy másik lapot, amely megjeleníti az összes jegyzetet (hívja meg AllNotesPage). Ezen a lapon a felhasználó kiválaszthatja a szerkesztőlapon megnyitni kívánt jegyzetet, hogy megtekinthesse, szerkessze vagy törölje azt. Azt is lehetővé kell tenni, hogy a felhasználó hozzon létre egy új megjegyzést.

Ehhez AllNotesPage rendelkeznie kell egy jegyzetgyűjteménysel, és meg kell jelenítenie a gyűjteményt. Az alkalmazás itt ütközik bajba, mert a jegyzetadatok szorosan kötődnek a NotePage fájlhoz. Ebben AllNotesPagea fájlban csak az összes jegyzetet szeretné megjeleníteni egy listában vagy más gyűjteménynézetben, az egyes jegyzetekkel kapcsolatos információkkal, például a létrehozás dátumával és a szöveg előnézetével. Mivel a jegyzetszöveg szorosan hozzá van kötve a TextBox vezérlőhöz, erre nincs mód.

Mielőtt hozzáad egy lapot az összes jegyzet megjelenítéséhez, hajtsunk végre néhány módosítást, hogy elkülönítsük a jegyzetadatokat a jegyzetbemutatótól.

Nézetek és modellek

Egy WinUI-alkalmazás általában legalább egy nézetréteggel és egy adatréteggel rendelkezik.

A nézetréteg XAML-korrektúra használatával határozza meg a felhasználói felületet. A korrektúra adatkötési kifejezéseket (például x:Bind) tartalmaz, amelyek meghatározzák az adott felhasználói felület összetevői és az adattagok közötti kapcsolatot. A kód mögötti fájlokat néha a nézetréteg részeként használják a felhasználói felület testreszabásához vagy módosításához, illetve az eseménykezelő argumentumok adatainak kinyeréséhez, mielőtt meghívna egy metódust, amely elvégzi az adatokon végzett munkát.

Az adatréteg vagy modell határozza meg az alkalmazás adatait és a kapcsolódó logikát képviselő típusokat. Ez a réteg független a nézetrétegétől, és több különböző nézetet is létrehozhat, amelyek interakcióba lépnek az adatokkal.

Jelenleg az NotePage adatok nézetét (a jegyzetszöveget) jelöli. Miután azonban beolvassa az adatokat az alkalmazásba a rendszerfájlból, az csak az Text in TextBoxtulajdonságában NotePage létezik. Nem úgy jelenik meg az alkalmazásban, hogy az adatokat különböző módokon vagy különböző helyeken jelenítse meg; vagyis az alkalmazás nem rendelkezik adatréteggel. Most át kell alakítania a projektet az adatréteg létrehozásához.

A nézet és a modell elkülönítése

Jótanács

Az oktatóanyag kódját a GitHub-adattárból töltheti le vagy tekintheti meg. A jelen lépésben szereplő kód megtekintéséhez tekintse meg a következő véglegesítést: jegyzetoldal – nézetmodell.

A meglévő kód újrabontásával válassza el a modellt a nézettől. A következő néhány lépés a kód rendszerezését fogja elvégezni, hogy a nézetek és modellek egymástól külön legyenek definiálva.

  1. A Megoldáskezelőben kattintson a jobb gombbal a projektre, és válassza az WinUINotesÚj mappa> lehetőséget. Nevezze el a mappát Models.

  2. Kattintson ismét a jobb gombbal a WinUINotes projektre, és válassza azÚj mappa> lehetőséget. Nevezze el a mappát Views.

  3. Keresse meg az NotePage.xaml elemet, és húzza a Views mappába. A NotePage.xaml.cs fájlnak vele együtt kell mozognia.

    Megjegyzés:

    Amikor áthelyez egy fájlt, a Visual Studio általában figyelmeztetést kap arról, hogy az áthelyezési művelet mennyi ideig tarthat. Ez itt nem jelenthet problémát, ha ezt a figyelmeztetést látja, nyomja le OK.

    A Visual Studio azt is megkérdezheti, hogy módosítani szeretné-e az áthelyezett fájl névterét. Válassza a Nem lehetőséget. A névteret a következő lépésekben módosíthatja.

A nézet névterének frissítése

Most, hogy a nézet át lett helyezve a Views mappába, frissítenie kell a névtereket az egyezéshez. A lapok XAML-fájljainak és kód mögötti fájljainak névtere WinUINotes. Ezt frissíteni kell a WinUINotes.Views.

  1. A Megoldáskezelő panelen bontsa ki NotePage.xaml a elemet a kód mögötti fájl megjelenítéséhez.

  2. Kattintson duplán az elemre a NotePage.xaml.cs kódszerkesztő megnyitásához, ha még nincs megnyitva. Módosítsa a névteret WinUINotes.Views:

    namespace WinUINotes.Views
    
  3. Kattintson duplán az elemre az NotePage.xaml XAML-szerkesztő megnyitásához, ha még nincs megnyitva. A régi névtérre a x:Class attribútum hivatkozik, amely meghatározza, hogy az XAML kód mögött melyik osztálytípus szerepel. Ez a bejegyzés nem csak a névtér, hanem a típussal rendelkező névtér is. Módosítsa a x:Class értékét WinUINotes.Views.NotePage:

    x:Class="WinUINotes.Views.NotePage"
    

A névtérhivatkozás javítása a MainWindow-ban

Az előző lépésben létrehozta a jegyzetoldalt, és frissítette MainWindow.xaml a lapra való navigáláshoz. Ne feledje, hogy a local: névtérleképezéssel van megfeleltetve. Gyakori eljárás, hogy a nevet local a projekt gyökérnévteréhez rendeli, és a Visual Studio projektsablonja ezt már elvégzi Ön helyett (xmlns:local="using:WinUINotes"). Most, hogy a lap új névtérbe került, az XAML típusleképezése érvénytelen.

Szerencsére igény szerint hozzáadhat saját névtérleképezéseket. Ehhez hozzá kell férnie a projektben létrehozott különböző mappák elemeihez. Ez az új XAML-névtér a névtérhez WinUINotes.Viewslesz megfeleltetve, így nevezze el.views A deklarációnak a következő attribútumhoz hasonlóan kell kinéznie: xmlns:views="using:WinUINotes.Views".

  1. A Megoldáskezelő panelen kattintson duplán a MainWindow.xaml bejegyzésre az XAML-szerkesztőben való megnyitásához.

  2. Adja hozzá ezt az új névtérleképezést a következő leképezés alatti sorhoz local:

    xmlns:views="using:WinUINotes.Views"
    
  3. Az local XAML névtér használatával állította be a Frame.SourcePageType tulajdonságot, ezért módosítsa arra views . Az XAML-nek így kell kinéznie:

    <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>
    
  4. Hozza létre és futtassa az alkalmazást. Az alkalmazásnak fordítói hibák nélkül kell futnia, és mindennek a korábbiakhoz hasonlóan kell működnie.

A modell definiálása

A modell (az adatok) jelenleg a jegyzetnézetben lesznek beágyazva. Létre fog hozni egy új osztályt a jegyzetoldal adatainak megjelenítéséhez:

  1. A Megoldáskezelő panelen kattintson a jobb gombbal a Models mappára, és válassza >osztály hozzáadása....

  2. Nevezze el az osztályt Note.cs , és nyomja le a Hozzáadás billentyűt. A Note.cs fájl megnyílik a kódszerkesztőben.

  3. Cserélje le a fájlban lévő kódot erre a Note.cs kódra, amely az osztályt public hozza létre, és tulajdonságokat és metódusokat ad hozzá a megjegyzés kezeléséhez:

    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();
                }
            }
        }
    }
    
  4. Mentse a fájlt.

Megfigyelheti, hogy ez a kód nagyon hasonlít a benne lévő NotePage.xaml.cskódhoz, néhány módosítással és kiegészítéssel.

Filename és Text tulajdonságokra public módosult, és új Date tulajdonság lett hozzáadva.

A fájlok mentésére és törlésére vonatkozó kód metódusokban public lett elhelyezve. Ez többnyire megegyezik a gombesemény-kezelőkben ClickNotePagehasznált kóddal, de a fájl törlése után a nézet frissítéséhez szükséges további kód. Erre nincs szükség, mert adatkötést fog használni a modell szinkronizálásának és megtekintésének megőrzéséhez.

Ezek az aszinkron metódus-aláírások feladat helyett void adnak vissza. Az Task osztály egyetlen aszinkron műveletet jelöl, amely nem ad vissza értéket. Kivéve, ha a metódus aláírása megköveteli void, ahogyan az eseménykezelők esetében is, Click a async metódusoknak egy Task.

A jegyzetet tartalmazó hivatkozásra sem fog többé hivatkozni StorageFile . Csak akkor próbálja lekérni a fájlt, ha szüksége van rá a mentéshez vagy a törléshez.

Ebben NotePagea fájlnévben egy helyőrzőt használt: note.txt. Most, hogy az alkalmazás több megjegyzést is támogat, a mentett jegyzetek fájlneveinek eltérőnek és egyedinek kell lenniük. Ehhez állítsa be a tulajdonságot Filename a konstruktorban. A DateTime.ToBinary metódussal létrehozhatja a fájlnév egy részét az aktuális idő alapján, és egyedivé teheti a fájlneveket. A létrehozott fájlnév így néz ki: notes-8584626598945870392.txt.

A jegyzetoldal frissítése

Most frissítheti a nézetet az NotePageNote adatmodell használatára, és törölheti a Note modellbe áthelyezett kódot.

  1. Nyissa meg a Nézetek\NotePage.xaml.cs fájlt, ha még nincs megnyitva a szerkesztőben.

  2. A lap tetején található utolsó using utasítás után adjon hozzá egy új using utasítást, amely hozzáférést biztosít a kódnak a mappában és a Models névtérben lévő osztályokhoz.

    using WinUINotes.Models;
    
  3. Törölje ezeket a sorokat az osztályból:

    private StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
    private StorageFile? noteFile = null;
    private string fileName = "note.txt";
    
  4. Ehelyett adjon hozzá egy Note , a helyükön elnevezett noteModel objektumot. Ez azokat a jegyzetadatokat jelöli, amelyek NotePage nézetet biztosítanak.

    private Note? noteModel;
    
  5. Már nincs szüksége az NotePage_Loaded eseménykezelőre. Nem fogja közvetlenül a szövegfájlból a Szövegdobozba beolvasni a szöveget. Ehelyett a jegyzet szövege objektumokba Note lesz beolvasva. Ehhez a kódhoz hozzá kell adnia a kódot, amikor hozzáadja a AllNotesPage következő lépésben. Törölje ezeket a sorokat.

    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);
        }
    }
    
  6. Cserélje le a metódusban szereplő kódot a SaveButton_Click következőre:

    if (noteModel is not null)
    {
        await noteModel.SaveAsync();
    }
    
  7. Cserélje le a metódusban szereplő kódot a DeleteButton_Click következőre:

    if (noteModel is not null)
    {
        await noteModel.DeleteAsync();
    }
    

Mostantól frissítheti az XAML-fájlt a Note modell használatára. Korábban közvetlenül a szövegfájlból olvasta be a szöveget a TextBox.Text kód mögötti fájl tulajdonságába. Most adatkötést használ a Text tulajdonsághoz.

  1. Nyissa meg a Nézetek\NotePage.xaml fájlt, ha még nincs megnyitva a szerkesztőben.

  2. Adjon hozzá egy Text attribútumot a TextBox vezérlőhöz. Kötés a Text következő tulajdonsághoz noteModel: Text="{x:Bind noteModel.Text, Mode=TwoWay}".

  3. Frissítse a Header következő tulajdonsághoz Date való kötést noteModel: 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"/>
    

Az adatkötéssel az alkalmazás felhasználói felülete megjelenítheti az adatokat, és igény szerint szinkronban maradhat az adatokkal. A Mode=TwoWay kötés beállítása azt jelenti, hogy a rendszer automatikusan szinkronizálja a TextBox.TextnoteModel.Text tulajdonságokat. Amikor a szöveg frissül a TextBoxfájlban, a módosítások megjelennek a Text tulajdonságban noteModel, és ha noteModel.Text módosul, a frissítések megjelennek a TextBox.

A Header tulajdonság az alapértelmezett ModeOneTime értéket használja, mert a noteModel.Date tulajdonság nem változik a fájl létrehozása után. Ez a kód az úgynevezett x:Bind hatékony funkcióját is bemutatja, amely lehetővé teszi, hogy a kötési útvonal egyik lépéséhez hasonló ToString függvényt használjon.

Fontos

Fontos a megfelelő BindingMode kiválasztása; ellenkező esetben előfordulhat, hogy az adatkötés nem a várt módon működik. (Gyakori hiba {x:Bind} , ha elfelejtjük módosítani az alapértelmezett beállítást BindingMode , amikor OneWay vagy TwoWay szükség van rá.)

Név Description
OneTime A céltulajdonság csak a kötés létrehozásakor frissül. Alapértelmezett beállítás a következőhöz {x:Bind}: .
OneWay Frissíti a céltulajdonságot a kötés létrehozásakor. A forrásobjektum módosításai a célra is propagálást végezhetnek. Alapértelmezett beállítás a következőhöz {Binding}: .
TwoWay Bármelyik módosításkor frissíti a célt vagy a forrásobjektumot. A kötés létrehozásakor a céltulajdonság frissül a forrásból.

Az adatkötés támogatja az adatok és a felhasználói felület elkülönítését, és ez egyszerűbb elméleti modellt, valamint az alkalmazás jobb olvashatóságát, tesztelhetőségét és karbantarthatóságát eredményezi.

A WinUI-ban kétféle kötés közül választhat:

  • A {x:Bind} korrektúrabővítmény fordítási időben lesz feldolgozva. Ennek néhány előnye a kötési kifejezések teljesítményének javítása és a fordítási idő ellenőrzése. A WinUI-alkalmazások kötéséhez ajánlott.
  • A {Binding} korrektúrabővítmény futásidőben lesz feldolgozva, és általános célú futtatókörnyezeti objektumvizsgálatot használ.

További információ a dokumentumokban:

Adatkötés és MVVM

A Model-View-ViewModel (MVVM) egy felhasználói felület architekturális tervezési mintája, amely a .NET-fejlesztők körében népszerű felhasználói felületi és nem felhasználói felületi kódok szétválasztására szolgál. A WinUI-alkalmazások létrehozásával kapcsolatos további információkért valószínűleg látni fogja és hallani fogja az említetteket. A nézetek és modellek elkülönítése, ahogyan itt is tette, az első lépés az alkalmazás teljes MVVM-implementációja felé, de az ebben az oktatóanyagban már elérhető.

Megjegyzés:

Ebben az oktatóanyagban a "modell" kifejezéssel hivatkoztunk az adatmodellre, de fontos megjegyezni, hogy ez a modell jobban igazodik a ViewModelhez egy teljes MVVM-implementációban, miközben a modell szempontjait is magában foglalja.

Az MVVM-ről az alábbi forrásokból tudhat meg többet: