Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Sekarang setelah Anda memiliki struktur proyek, Anda dapat mulai menerapkan pola MVVM dengan menggunakan Toolkit MVVM. Langkah ini melibatkan pembuatan ViewModels yang memanfaatkan fitur MVVM Toolkit, seperti ObservableObject untuk pemberitahuan perubahan properti dan RelayCommand untuk implementasi perintah.
Menginstal paket MVVM Toolkit NuGet
Anda perlu menginstal Toolkit MVVM di proyek WinUINotes dan WinUINotes.Bus .
Menggunakan Visual Studio
- Klik kanan pada proyek WinUINotes.Bus di Penjelajah Solusi.
- Pilih Kelola Paket NuGet.
- Cari CommunityToolkit.Mvvm dan instal versi stabil terbaru.
- Ulangi langkah-langkah ini untuk proyek WinUINotes .
Menggunakan .NET CLI
Atau, Anda dapat menggunakan .NET CLI untuk menginstal paket:
dotnet add WinUINotes.Bus package CommunityToolkit.Mvvm
dotnet add WinUINotes package CommunityToolkit.Mvvm
Keputusan desain untuk lapisan model
Saat Anda menerapkan MVVM, penting untuk memutuskan cara menyusun kelas model Anda sehubungan dengan ViewModels. Dalam tutorial ini, kelas model (Note dan AllNotes) bertanggung jawab atas representasi data, logika bisnis, dan memperbarui penyimpanan data. ViewModels menangani properti yang dapat diamati, mengubah pemberitahuan, dan perintah untuk interaksi UI.
Dalam implementasi yang lebih sederhana, Anda dapat menggunakan objek CLR (POCO) lama biasa untuk kelas model tanpa logika bisnis atau metode akses data. Dalam hal ini, ViewModels menangani semua operasi data melalui lapisan layanan. Namun, untuk tutorial ini, kelas model mencakup metode untuk memuat, menyimpan, dan menghapus catatan untuk memberikan pemisahan kekhawatiran yang lebih jelas dan menjaga ViewModels tetap fokus pada logika presentasi.
Memindahkan model Note
Pindahkan Note kelas ke proyek WinUINotes.Bus . Ini tetap menjadi kelas model sederhana dengan beberapa logika untuk representasi data dan manajemen status tetapi tanpa fitur Toolkit MVVM apa pun. ViewModels menangani properti yang dapat diamati dan mengubah pemberitahuan, bukan model itu sendiri.
Di proyek WinUINotes.Bus , buat folder baru bernama Model.
Pindahkan
Note.csfile dari proyek WinUINotes ke folder WinUINotes.Bus/Models .Perbarui namespace agar sesuai dengan lokasi baru:
namespace WinUINotes.Models { public class Note { // Existing code remains unchanged ... } }
Kelas Note ini adalah model data sederhana. Ini tidak memerlukan pemberitahuan perubahan karena ViewModels mengelola properti yang dapat diamati dan memberi tahu UI perubahan.
Pindahkan model AllNotes
Pindahkan AllNotes kelas ke proyek WinUINotes.Bus .
Pindahkan
AllNotes.csfile dari proyek WinUINotes ke folder WinUINotes.Bus/Models .Perbarui namespace agar sesuai dengan lokasi baru:
namespace WinUINotes.Models { public class AllNotes { // Existing code remains unchanged ... } }
Seperti kelasnya Note , AllNotes adalah kelas model sederhana. ViewModel menangani perilaku yang dapat diamati dan mengelola kumpulan catatan.
Membuat AllNotesViewModel
Di proyek WinUINotes.Bus , buat folder baru bernama ViewModels.
Tambahkan file kelas baru bernama
AllNotesViewModel.csdengan konten berikut: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); } } } }
Pengelola AllNotesViewModel mengelola kumpulan catatan yang ditampilkan di UI:
-
[ObservableProperty]: Bidangnotessecara otomatis menghasilkan properti publikNotesdengan pemberitahuan perubahan. Saat koleksiNotesberubah, UI akan diperbarui secara otomatis. -
allNotesmodel: Bidang privat ini menyimpan instansAllNotesmodel, yang menangani operasi data aktual. -
[RelayCommand]: Atribut ini menghasilkanLoadCommandproperti dariLoadAsync()metode , memungkinkan UI untuk memicu operasi pemuatan melalui pengikatan data. -
LoadAsync()metode: Metode ini memuat catatan dari model, menghapus koleksi yang dapat diamati saat ini, dan mengisinya dengan catatan yang dimuat. Pola ini memastikan koleksi terikat UI tetap disinkronkan dengan data yang mendasar.
Pemisahan antara allNotes model (operasi data) dan Notes koleksi yang dapat diamati (pengikatan UI) adalah pola MVVM kunci yang menjaga tanggung jawab terpisah, dan memastikan Tampilan tetap sinkron dengan data dari ViewModel.
Pelajari selengkapnya di dokumen:
Membuat NoteViewModel
Di folder ViewModels , tambahkan file kelas baru bernama
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(); } } }
Ini NoteViewModel menunjukkan beberapa fitur utama dari Toolkit MVVM:
-
[ObservableProperty]: Bidangfilename,text, dandatesecara otomatis menghasilkan properti publik (Filename,Text,Date) dengan dukungan pemberitahuan perubahan. -
[NotifyCanExecuteChangedFor]: Atribut ini memastikan bahwa ketikaFilenameatauTextberubah, perintah terkait mengevaluasi kembali apakah dapat dijalankan. Misalnya, saat Anda mengetik teks, tombol Simpan secara otomatis mengaktifkan atau menonaktifkan berdasarkan logika validasi. -
[RelayCommand(CanExecute = nameof(CanSave))]: Atribut ini menghasilkan propertiSaveCommandyang terikat ke metode validasiCanSave(). Perintah hanya diaktifkan ketika keduanyaTextdanFilenamememiliki nilai. -
InitializeForExistingNote(): Metode ini memuat data catatan yang ada ke properti ViewModel, yang kemudian memperbarui UI melalui pengikatan data. -
Simpan logika: Metode tersebut memperbarui model dasar
Notedengan nilai properti saat ini dan memanggilSaveAsync()pada model. Setelah disimpan, ini memberi tahuDeleteCommandbahwa file harus dievaluasi ulang (karena file sekarang ada dan dapat dihapus). -
Menghapus logika: Metode
Delete()memanggilDeleteAsync()model catatan dan membuat catatan kosong baru.
Kemudian dalam tutorial ini, Anda mengintegrasikan layanan file untuk menangani operasi file aktual dan menggunakan kelas MVVM Toolkit WeakReferenceMessenger untuk memberi tahu bagian lain dari aplikasi ketika catatan dihapus sambil tetap digabungkan secara longgar.
Pelajari selengkapnya di dokumen:
Memperbarui tampilan untuk menggunakan ViewModels
Sekarang Anda perlu memperbarui halaman XAML anda untuk mengikat ke ViewModels baru.
Perbarui tampilan AllNotesPage
Di
AllNotesPage.xaml, perbarui pengikatanItemsSourceItemsViewuntuk menggunakan properti ViewModelNotes:<ItemsView ItemsSource="{x:Bind viewModel.Notes}" ...AllNotesPage.xaml.csPerbarui file agar terlihat seperti ini: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(); } } } }
Dalam file code-behind ini, konstruktor langsung membuat instans AllNotesViewModel. Metode OnNavigatedTo() memanggil LoadAsync() metode pada ViewModel saat halaman dinavigasi. Metode ini memuat catatan dari penyimpanan dan memperbarui koleksi yang dapat diamati. Pola ini memastikan data selalu di-refresh saat pengguna menavigasi ke halaman semua catatan.
Kemudian dalam tutorial ini, Anda merefaktor kode ini untuk menggunakan injeksi dependensi, yang memungkinkan ViewModel disuntikkan ke konstruktor halaman alih-alih dibuat secara langsung. Pendekatan ini meningkatkan kemampuan pengujian dan memudahkan pengelolaan siklus hidup ViewModel.
Memperbarui tampilan NotePage
Di
NotePage.xaml, perbarui pengikatanTextBoxuntukTextdanHeaderuntuk menggunakan properti ViewModel. Perbarui tombolStackPaneluntuk mengikat perintah alih-alih menggunakanClickperistiwa:... <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> ...Anda juga mengatur
UpdateSourceTriggerpada pengikatanTextBox.Textuntuk memastikan perubahan dikirim ke ViewModel saat pengguna mengetik. Pengaturan ini memungkinkan tombolSaveuntuk mengaktifkan atau menonaktifkan secara real-time berdasarkan input.Di
NotePage.xaml.cs, perbarui kode untuk menggunakanNoteViewModel: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); } } } }Peristiwa
ClickuntukSavedanDeletedihapus karena tombol sekarang terikat langsung pada perintah di ViewModel.NoteViewModeldiinstansiasi dalam metodeOnNavigatedTo().NoteJika sebuah parameter diteruskan, itu akan menginisialisasi ViewModel dengan data catatan yang ada.
Pelajari selengkapnya di dokumen:
Windows developer