Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Maintenant que vous disposez de la structure du projet, vous pouvez commencer à implémenter le modèle MVVM à l’aide du kit de ressources MVVM. Cette étape implique la création de ViewModels qui tirent parti des fonctionnalités du kit de ressources MVVM, telles que ObservableObject la notification de modification de propriété et RelayCommand l’implémentation de commandes.
Installer le package NuGet du kit de ressources MVVM
Vous devez installer le kit de ressources MVVM dans les projets WinUINotes et WinUINotes.Bus .
Utilisation de Visual Studio
- Cliquez avec le bouton droit sur le projet WinUINotes.Bus dans l’Explorateur de solutions.
- Sélectionnez Gérer les packages NuGet.
- Recherchez CommunityToolkit.Mvvm et installez la dernière version stable.
- Répétez ces étapes pour le projet WinUINotes .
Utilisation de l’interface CLI .NET
Vous pouvez également utiliser l’interface CLI .NET pour installer le package :
dotnet add WinUINotes.Bus package CommunityToolkit.Mvvm
dotnet add WinUINotes package CommunityToolkit.Mvvm
Décisions de conception pour la couche de modèle
Lorsque vous implémentez MVVM, il est important de décider comment structurer vos classes de modèle par rapport aux ViewModels. Dans ce tutoriel, les classes de modèle (Note et AllNotes) sont responsables de la représentation des données, de la logique métier et de la mise à jour du stockage des données. Les ViewModels gèrent les propriétés observables, la notification de modification et les commandes pour l’interaction de l’interface utilisateur.
Dans une implémentation plus simple, vous pouvez utiliser des objets CLR simples (POCO) pour les classes de modèle sans aucune logique métier ou méthodes d’accès aux données. Dans ce cas, les ViewModels gèrent toutes les opérations de données via la couche de service. Toutefois, pour ce didacticiel, les classes de modèle incluent des méthodes de chargement, d’enregistrement et de suppression de notes pour fournir une séparation plus claire des préoccupations et garder les ViewModels concentrés sur la logique de présentation.
Déplacer le modèle de note
Déplacez la Note classe vers le projet WinUINotes.Bus . Il reste une classe de modèle simple avec une logique pour la représentation des données et la gestion de l’état, mais sans aucune fonctionnalité du kit de ressources MVVM. Les ViewModels gèrent les propriétés observables et la notification de modification, et non le modèle lui-même.
Dans le projet WinUINotes.Bus , créez un dossier nommé Models.
Déplacez le
Note.csfichier du projet WinUINotes vers le dossier WinUINotes.Bus/Models .Mettez à jour l’espace de noms pour qu’il corresponde au nouvel emplacement :
namespace WinUINotes.Models { public class Note { // Existing code remains unchanged ... } }
La Note classe est un modèle de données simple. Il n’a pas besoin de notification de modification, car les ViewModels gèrent les propriétés observables et informent l’interface utilisateur des modifications.
Déplacer le modèle AllNotes
Déplacez la AllNotes classe vers le projet WinUINotes.Bus .
Déplacez le
AllNotes.csfichier du projet WinUINotes vers le dossier WinUINotes.Bus/Models .Mettez à jour l’espace de noms pour qu’il corresponde au nouvel emplacement :
namespace WinUINotes.Models { public class AllNotes { // Existing code remains unchanged ... } }
Comme la Note classe, AllNotes est une classe de modèle simple. ViewModel gère le comportement observable et gère la collection de notes.
Créer le AllNotesViewModel
Dans le projet WinUINotes.Bus , créez un dossier nommé ViewModels.
Ajoutez un nouveau fichier de classe nommé
AllNotesViewModel.csavec le contenu suivant :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); } } } }
AllNotesViewModel gère la collection de notes affichée dans l’interface utilisateur.
-
[ObservableProperty]: lenoteschamp génère automatiquement une propriété publiqueNotesavec notification de modification. Lorsque laNotescollection change, l’interface utilisateur est automatiquement mise à jour. -
allNotesmodèle : ce champ privé contient une instance duAllNotesmodèle, qui gère les opérations de données réelles. -
[RelayCommand]: cet attribut génère uneLoadCommandpropriété à partir de laLoadAsync()méthode, ce qui permet à l’interface utilisateur de déclencher l’opération de chargement via la liaison de données. -
LoadAsync()méthode : cette méthode charge les notes du modèle, efface la collection observable actuelle et la remplit avec les notes chargées. Ce modèle garantit que la collection liée à l’interface utilisateur reste synchronisée avec les données sous-jacentes.
La séparation entre le allNotes modèle (opérations de données) et la Notes collection observable (liaison d’interface utilisateur) est un modèle MVVM clé qui conserve les préoccupations séparées et la vue synchronisée avec les données de ViewModel.
En savoir plus dans la documentation :
Créer le NoteViewModel
Dans le dossier ViewModels , ajoutez un nouveau fichier de classe nommé
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(); } } }
Le kit NoteViewModel illustre plusieurs fonctionnalités clés du MVVM :
-
[ObservableProperty]: Les champsfilename,text, etdategénèrent automatiquement des propriétés publiques (Filename,Text,Date) avec prise en charge des notifications de changements. -
[NotifyCanExecuteChangedFor]: cet attribut garantit que lorsqueFilenameouTextchange, les commandes associées réévaluent s’ils peuvent s’exécuter. Par exemple, lorsque vous tapez du texte, le bouton Enregistrer active ou désactive automatiquement en fonction de la logique de validation. -
[RelayCommand(CanExecute = nameof(CanSave))]: Cet attribut génère uneSaveCommandpropriété liée à la méthodeCanSave()de validation. La commande est activée uniquement lorsque les deuxTextetFilenameont des valeurs. -
InitializeForExistingNote(): cette méthode charge les données d’une note existante dans les propriétés ViewModel, qui mettent ensuite à jour l’interface utilisateur via la liaison de données. -
Logique d’enregistrement : la
Save()méthode met à jour le modèle sous-jacentNoteavec les valeurs de propriété actuelles et appelleSaveAsync()sur le modèle. Après l’enregistrement, il informe leDeleteCommandqu’il doit réévaluer (dans la mesure où un fichier existe maintenant et peut être supprimé). -
Logique de suppression : la
Delete()méthode appelleDeleteAsync()le modèle de note et crée une note vide.
Plus loin dans ce tutoriel, vous intégrez le service de fichiers pour gérer les opérations de fichier réelles et utilisez la classe du MVVM Toolkit pour notifier d'autres parties de l'application lorsqu'une note est supprimée tout en maintenant un couplage lâche.
En savoir plus dans la documentation :
Mettre à jour les vues pour utiliser les ViewModels
Vous devez maintenant mettre à jour vos pages XAML pour établir une liaison avec les nouveaux ViewModels.
Mettre à jour la vue AllNotesPage
Dans
AllNotesPage.xaml, mettez à jour la liaisonItemsSourcedeItemsViewpour utiliser la propriétéNotesdu ViewModel.<ItemsView ItemsSource="{x:Bind viewModel.Notes}" ...Mettez à jour le fichier pour qu’il
AllNotesPage.xaml.csressemble à ceci :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(); } } } }
Dans ce fichier code-behind, le constructeur instancie directement le AllNotesViewModel. La méthode OnNavigatedTo() appelle la méthode LoadAsync() sur le ViewModel lorsque la page est consultée. Cette méthode charge les notes du stockage et met à jour la collection observable. Ce modèle garantit que les données sont toujours actualisées lorsque l’utilisateur accède à la page de toutes les notes.
Plus loin dans ce tutoriel, vous refactorisez ce code pour utiliser l’injection de dépendances, ce qui permet à ViewModel d’être injecté dans le constructeur de page au lieu d’être créé directement. Cette approche améliore la testabilité et facilite la gestion des cycles de vie ViewModel.
Mettre à jour la vue NotePage
Dans
NotePage.xaml, mettez à jour les liaisons de donnéesTextBoxpourTextetHeaderafin d'utiliser les propriétés du ViewModel. Mettez à jour les boutonsStackPanelpour les lier aux commandes au lieu d’utiliser les événementsClick:... <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> ...Vous avez également défini
UpdateSourceTriggersur laTextBox.Textliaison pour vous assurer que les modifications sont envoyées au ViewModel au fur et à mesure que l'utilisateur tape. Ce paramètre permet auSavebouton d’activer ou de désactiver en temps réel en fonction de l’entrée.Dans
NotePage.xaml.cs, mettez à jour le code pour utiliser leNoteViewModel.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); } } } }Les
Clickévénements pourSaveetDeletesont supprimés, car les boutons se lient désormais directement aux commandes dans ViewModel.NoteViewModelest instancié dans la méthodeOnNavigatedTo(). Si unNoteparamètre est passé, il initialise le ViewModel avec les données de note existantes.
En savoir plus dans la documentation :
Windows developer