Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Teraz, gdy masz już strukturę projektu, możesz zacząć implementować wzorzec MVVM przy użyciu zestawu narzędzi MVVM Toolkit. Ten krok obejmuje utworzenie modeli ViewModel, które korzystają z funkcji zestawu narzędzi MVVM Toolkit, takich jak ObservableObject powiadomienie o zmianie właściwości i RelayCommand implementacja poleceń.
Zainstaluj pakiet NuGet dla MVVM Toolkit
Należy zainstalować zestaw narzędzi MVVM w projektach WinUINotes i WinUINotes.Bus .
Korzystanie z programu Visual Studio
- Kliknij prawym przyciskiem myszy projekt WinUINotes.Bus w Eksploratorze rozwiązań.
- Wybierz Zarządzaj pakietami NuGet.
- Wyszukaj CommunityToolkit.Mvvm i zainstaluj najnowszą stabilną wersję.
- Powtórz te kroki dla projektu WinUINotes .
Korzystanie z .NET CLI
Alternatywnie możesz użyć interfejsu wiersza polecenia platformy .NET do zainstalowania pakietu:
dotnet add WinUINotes.Bus package CommunityToolkit.Mvvm
dotnet add WinUINotes package CommunityToolkit.Mvvm
Decyzje projektowe dotyczące warstwy modelu
Podczas implementacji wzorca MVVM ważne jest, aby zdecydować, jak zorganizować klasy modelu w odniesieniu do ViewModeli. W tym samouczku klasy modeli (Note i AllNotes) są odpowiedzialne za reprezentację danych, logikę biznesową i aktualizowanie magazynu danych. Modele Widoków obsługują właściwości obserwowalne, powiadomienia o zmianach i polecenia dla interakcji z interfejsem użytkownika.
W prostszej implementacji można użyć zwykłych starych obiektów CLR (POC) dla klas modelu bez żadnej logiki biznesowej lub metod dostępu do danych. W takim przypadku ViewModels zarządza wszystkimi operacjami na danych za pośrednictwem warstwy serwisowej. Jednak w tym samouczku klasy modeli obejmują metody ładowania, zapisywania i usuwania notatek, aby zapewnić jaśniejsze rozdzielenie zagadnień i zachować model ViewModels skoncentrowany na logice prezentacji.
Przenieś model Note
Przenieś klasę Note do projektu WinUINotes.Bus . Pozostaje to prosta klasa modelu z pewną logiką na potrzeby reprezentacji danych i zarządzania stanem, ale bez żadnych funkcji zestawu narzędzi MVVM Toolkit. Model widoków obsługuje obserwowalne właściwości i powiadomienia o zmianie, a nie sam model.
W projekcie WinUINotes.Bus utwórz nowy folder o nazwie Models.
Przenieś plik z projektu
Note.csdo folderu WinUINotes.Bus/Models.Zaktualizuj przestrzeń nazw, aby odpowiadała nowej lokalizacji:
namespace WinUINotes.Models { public class Note { // Existing code remains unchanged ... } }
Klasa Note jest prostym modelem danych. Nie wymaga powiadomienia o zmianie, ponieważ model ViewModels zarządza obserwowalnymi właściwościami i powiadamia interfejs użytkownika o zmianach.
Przenoszenie modelu AllNotes
Przenieś klasę AllNotes do projektu WinUINotes.Bus .
Przenieś plik z projektu
AllNotes.csdo folderu WinUINotes.Bus/Models.Zaktualizuj przestrzeń nazw, aby odpowiadała nowej lokalizacji:
namespace WinUINotes.Models { public class AllNotes { // Existing code remains unchanged ... } }
Note Podobnie jak klasa, AllNotes jest prostą klasą modelu. ViewModel obsługuje zachowaniem obserwowalnym i zarządza zbiorem notatek.
Tworzenie modelu AllNotesViewModel
W projekcie WinUINotes.Bus utwórz nowy folder o nazwie ViewModels.
Dodaj nowy plik klasy o nazwie
AllNotesViewModel.csz następującą zawartością:using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using System.Collections.ObjectModel; using System.Threading.Tasks; using WinUINotes.Models; namespace WinUINotes.ViewModels { public partial class AllNotesViewModel : ObservableObject { private readonly AllNotes allNotes; [ObservableProperty] private ObservableCollection<Note> notes; public AllNotesViewModel() { allNotes = new AllNotes(); notes = new ObservableCollection<Note>(); } [RelayCommand] public async Task LoadAsync() { await allNotes.LoadNotes(); Notes.Clear(); foreach (var note in allNotes.Notes) { Notes.Add(note); } } } }
Moduł AllNotesViewModel zarządza kolekcją notatek wyświetlanych w interfejsie użytkownika.
-
[ObservableProperty]: Polenotesautomatycznie generuje właściwość publicznąNotesz powiadomieniem o zmianie.NotesGdy kolekcja ulegnie zmianie, interfejs użytkownika zostanie automatycznie zaktualizowany. -
allNotesmodel: to pole prywatne zawiera wystąpienieAllNotesmodelu, które obsługuje rzeczywiste operacje na danych. -
[RelayCommand]: Ten atrybut generujeLoadCommandwłaściwość zLoadAsync()metody, umożliwiając interfejsowi użytkownika wyzwalanie operacji ładowania za pomocą powiązania danych. -
LoadAsync()metoda: Ta metoda ładuje notatki z modelu, czyści bieżącą obserwowaną kolekcję i wypełnia je załadowanymi notatkami. Ten wzorzec gwarantuje, że kolekcja powiązana z interfejsem użytkownika pozostaje zsynchronizowana z danymi bazowymi.
Rozdzielenie allNotes modelu (operacji danych) i obserwowalnej Notes kolekcji (powiązanie interfejsu użytkownika) to kluczowy wzorzec MVVM, który zachowuje obawy oddzielone, a widok zsynchronizowany z danymi modelu ViewModel.
Dowiedz się więcej w dokumentacji:
Tworzenie modelu NoteViewModel
W folderze ViewModels dodaj nowy plik klasy o nazwie
NoteViewModel.cs:using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using System; using System.Threading.Tasks; using WinUINotes.Models; namespace WinUINotes.ViewModels { public partial class NoteViewModel : ObservableObject { private Note note; [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(SaveCommand))] [NotifyCanExecuteChangedFor(nameof(DeleteCommand))] private string filename = string.Empty; [ObservableProperty] [NotifyCanExecuteChangedFor(nameof(SaveCommand))] private string text = string.Empty; [ObservableProperty] private DateTime date = DateTime.Now; public NoteViewModel() { this.note = new Note(); this.Filename = note.Filename; } public void InitializeForExistingNote(Note note) { this.note = note; this.Filename = note.Filename; this.Text = note.Text; this.Date = note.Date; } [RelayCommand(CanExecute = nameof(CanSave))] private async Task Save() { note.Filename = this.Filename; note.Text = this.Text; note.Date = this.Date; await note.SaveAsync(); // Check if the DeleteCommand can now execute // (it can if the file now exists) DeleteCommand.NotifyCanExecuteChanged(); } private bool CanSave() { return note is not null && !string.IsNullOrWhiteSpace(this.Text) && !string.IsNullOrWhiteSpace(this.Filename); } [RelayCommand(CanExecute = nameof(CanDelete))] private async Task Delete() { await note.DeleteAsync(); note = new Note(); } private bool CanDelete() { // Note: This is to illustrate how commands can be // enabled or disabled. // In a real application, you shouldn't perform // file operations in your CanExecute logic. return note is not null && !string.IsNullOrWhiteSpace(this.Filename) && this.note.NoteFileExists(); } } }
Demonstruje NoteViewModel kilka kluczowych funkcji zestawu narzędzi MVVM Toolkit:
-
[ObservableProperty]: Polafilename,textidateautomatycznie generują właściwości publiczne (Filename,Text,Date) z obsługą powiadomień o zmianie. -
[NotifyCanExecuteChangedFor]: Ten atrybut gwarantuje, że gdyFilenamelubTextzmieni się, skojarzone polecenia ponownie ocenią, czy mogą być wykonywane. Na przykład po wpisaniu tekstu przycisk Zapisz automatycznie włącza lub wyłącza na podstawie logiki walidacji. -
[RelayCommand(CanExecute = nameof(CanSave))]: Ten atrybut generuje właściwość powiązanąSaveCommandz metodąCanSave()weryfikacji . Polecenie jest włączone tylko wtedy, gdy zarównoText, jak iFilenamemają wartości. -
InitializeForExistingNote(): Ta metoda ładuje dane istniejącej notatki do właściwości ViewModel, które następnie aktualizują interfejs użytkownika za pomocą powiązania danych. -
Logika zapisu:
Save()metoda aktualizuje model bazowyNoteprzy użyciu bieżących wartości właściwości i wywołujeSaveAsync()na modelu. Po zapisaniu powiadamiaDeleteCommando tym, że powinien zostać ponownie obliczony (ponieważ plik istnieje teraz i można go usunąć). -
Logika usuwania: Metoda
Delete()wywołujeDeleteAsync()na modelu notatki i tworzy nową pustą notatkę.
Dalej w tym samouczku, zintegrujesz usługę plików w celu obsługi rzeczywistych operacji na plikach i użyjesz klasy WeakReferenceMessenger narzędzia MVVM Toolkit, aby powiadomić inne części aplikacji, gdy notatka zostanie usunięta, pozostając luźno powiązaną.
Dowiedz się więcej w dokumentacji:
Aktualizowanie widoków w celu korzystania z modelu ViewModels
Teraz musisz zaktualizować strony XAML, aby powiązać je z nowymi modelami ViewModels.
Aktualizowanie widoku AllNotesPage
W
AllNotesPage.xamlpliku zaktualizujItemsSourcepowiązanieItemsView, aby użyć właściwości ViewModeluNotes.<ItemsView ItemsSource="{x:Bind viewModel.Notes}" ...Zaktualizuj plik
AllNotesPage.xaml.cs, aby wyglądał następująco:using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Navigation; using WinUINotes.ViewModels; namespace WinUINotes.Views { public sealed partial class AllNotesPage : Page { private AllNotesViewModel? viewModel; public AllNotesPage() { this.InitializeComponent(); viewModel = new AllNotesViewModel(); } private void NewNoteButton_Click(object sender, RoutedEventArgs e) { Frame.Navigate(typeof(NotePage)); } private void ItemsView_ItemInvoked(ItemsView sender, ItemsViewItemInvokedEventArgs args) { Frame.Navigate(typeof(NotePage), args.InvokedItem); } protected override async void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); if (viewModel is not null) { await viewModel.LoadAsync(); } } } }
W tym pliku code-behind konstruktor tworzy wystąpienie AllNotesViewModel bezpośrednio. Metoda OnNavigatedTo() wywołuje metodę LoadAsync() w modelu ViewModel po przejściu do strony. Ta metoda ładuje notatki z magazynu i aktualizuje obserwowaną kolekcję. Ten wzorzec gwarantuje, że dane są zawsze odświeżane, gdy użytkownik przejdzie do strony wszystkich notatek.
W dalszej części tego samouczka refaktoryzujesz ten kod w celu użycia wstrzykiwania zależności, co umożliwia wstrzyknięcie modelu ViewModel do konstruktora strony zamiast bezpośredniego tworzenia. Takie podejście zwiększa możliwość testowania i ułatwia zarządzanie cyklami życia modelu ViewModel.
Aktualizowanie widoku NotePage
W
NotePage.xaml, zaktualizuj powiązaniaTextBoxdlaTextiHeader, aby używać właściwości ViewModel.StackPanelZaktualizuj przyciski, aby powiązać z poleceniami zamiast używać zdarzeńClick:... <TextBox x:Name="NoteEditor" Text="{x:Bind noteVm.Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AcceptsReturn="True" TextWrapping="Wrap" PlaceholderText="Enter your note" Header="{x:Bind noteVm.Date.ToString()}" ScrollViewer.VerticalScrollBarVisibility="Auto" MaxWidth="400" Grid.Column="1"/> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Spacing="4" Grid.Row="1" Grid.Column="1"> <Button Content="Save" Command="{x:Bind noteVm.SaveCommand}"/> <Button Content="Delete" Command="{x:Bind noteVm.DeleteCommand}"/> </StackPanel> ...Należy również ustawić powiązanie
UpdateSourceTriggernaTextBox.Text, aby upewnić się, że zmiany są wysyłane do modelu ViewModel w trakcie pisania przez użytkownika. Ustawienie to pozwala, aby przyciskSavebył włączany lub wyłączany w czasie rzeczywistym na podstawie danych wejściowych.W
NotePage.xaml.cspliku zaktualizuj kod, aby używałNoteViewModel:using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Navigation; using WinUINotes.Models; using WinUINotes.ViewModels; namespace WinUINotes.Views { public sealed partial class NotePage : Page { private NoteViewModel? noteVm; public NotePage() { this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); noteVm = new NoteViewModel(); if (e.Parameter is Note note && noteVm is not null) { noteVm.InitializeForExistingNote(note); } } } }Zdarzenia
Clickdla elementuSaveiDeletesą usuwane, ponieważ przyciski są teraz powiązane bezpośrednio z poleceniami w modelu ViewModel.NoteViewModeljest instancjonowany w metodzieOnNavigatedTo(). Jeśli zostanie przekazany parametrNote, inicjuje ViewModel z danymi istniejącej notatki.
Dowiedz się więcej w dokumentacji:
Windows developer