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.
ObservableObject adalah kelas dasar untuk objek yang dapat diamati dengan mengimplementasikan INotifyPropertyChanged antarmuka dan INotifyPropertyChanging . Ini dapat digunakan sebagai titik awal untuk semua jenis objek yang perlu mendukung pemberitahuan perubahan properti.
API Platform:
ObservableObject,TaskNotifier,TaskNotifier<T>
Cara kerjanya
ObservableObject memiliki fitur utama berikut:
- Ini menyediakan implementasi dasar untuk
INotifyPropertyChangeddanINotifyPropertyChanging, serta mengekspos peristiwaPropertyChangeddanPropertyChanging. - Ini menyediakan serangkaian metode
SetPropertyyang dapat digunakan untuk mengatur nilai properti pada tipe yang mewarisiObservableObjectdengan mudah, dan untuk secara otomatis memicu event yang sesuai. - Metode
SetPropertyAndNotifyOnCompletiondisediakan, yang serupa denganSetPropertytetapi memiliki kemampuan untuk menetapkan propertiTaskdan memicu event notifikasi secara otomatis saat tugas yang ditetapkan selesai. - Ini mengekspos metode
OnPropertyChangeddanOnPropertyChanging, yang dapat dioverride dalam tipe turunan untuk menyesuaikan cara event notifikasi dipicu.
Properti sederhana
Berikut adalah contoh cara menerapkan dukungan pemberitahuan ke properti kustom:
public class User : ObservableObject
{
private string name;
public string Name
{
get => name;
set => SetProperty(ref name, value);
}
}
Metode yang disediakan SetProperty<T>(ref T, T, string) memeriksa nilai properti saat ini, dan memperbaruinya jika berbeda, lalu juga menaikkan peristiwa yang relevan secara otomatis. Nama properti secara otomatis diambil melalui penggunaan [CallerMemberName] atribut, jadi tidak perlu menentukan properti mana yang sedang diperbarui secara manual.
Membungkus model yang tidak dapat diamati
Skenario yang umum, misalnya saat bekerja dengan item basis data, adalah membuat model pembungkus yang "bindable" yang meneruskan properti-properti model basis data dan memicu notifikasi perubahan properti saat diperlukan. Ini juga diperlukan ketika ingin menyuntikkan dukungan pemberitahuan ke model, yang tidak mengimplementasikan INotifyPropertyChanged antarmuka.
ObservableObject menyediakan metode khusus untuk membuat proses ini lebih sederhana. Untuk contoh berikut, User adalah model yang langsung memetakan tabel database, tanpa mewarisi dari ObservableObject:
public class ObservableUser : ObservableObject
{
private readonly User user;
public ObservableUser(User user) => this.user = user;
public string Name
{
get => user.Name;
set => SetProperty(user.Name, value, user, (u, n) => u.Name = n);
}
}
Dalam hal ini kita menggunakan SetProperty<TModel, T>(T, T, TModel, Action<TModel, T>, string) kelebihan beban. Tanda tangan sedikit lebih kompleks daripada yang sebelumnya - ini perlu untuk membiarkan kode masih sangat efisien bahkan jika kita tidak memiliki akses ke bidang dukungan seperti dalam skenario sebelumnya. Kita dapat melalui setiap bagian dari tanda tangan metode ini secara rinci untuk memahami peran komponen yang berbeda:
-
TModeladalah argumen jenis, menunjukkan jenis model yang kita bungkus. Dalam kasus ini, ini adalah kelasUserkita. Perhatikan bahwa kita tidak perlu menentukan ini secara eksplisit - pengkompilasi C# akan menyimpulkan ini secara otomatis dengan cara kita memanggil metode .SetProperty -
Tadalah jenis properti yang ingin kita tetapkan. Seperti halnyaTModel, hal ini disimpulkan secara otomatis. -
T oldValueadalah parameter pertama, dan dalam hal ini kita menggunakanuser.Nameuntuk meneruskan nilai saat ini dari properti yang sedang kita bungkus. -
T newValueadalah nilai baru yang ditetapkan ke properti tersebut, dan di sini kita meneruskanvalue, yang merupakan nilai masukan di dalam setter properti. -
TModel modeladalah model target yang kita bungkus; dalam hal ini, kita meneruskan instans yang disimpan dalam fielduser. -
Action<TModel, T> callbackadalah fungsi yang akan dipanggil jika nilai baru properti berbeda dari yang saat ini, dan properti perlu diatur. Ini akan dilakukan oleh fungsi callback ini, yang menerima model target dan nilai properti baru yang akan ditetapkan sebagai masukan. Dalam hal ini kami hanya menetapkan nilai input (yang kami panggiln) keNameproperti (dengan melakukanu.Name = n). Penting di sini untuk menghindari pengambilan nilai dari cakupan saat ini dan hanya berinteraksi dengan yang diberikan sebagai input ke panggilan balik, karena ini memungkinkan pengkompilasi C# untuk menyimpan fungsi panggilan balik dan melakukan sejumlah peningkatan performa. Karena itulah kita tidak langsung mengakses fielduserdi sini atau parametervaluedi setter, melainkan hanya menggunakan parameter masukan untuk ekspresi lambda.
Metode ini SetProperty<TModel, T>(T, T, TModel, Action<TModel, T>, string) membuat pembuatan properti pembungkusan ini sangat sederhana, karena mengurus pengambilan dan pengaturan properti target sambil menyediakan API yang sangat ringkas.
Catatan
Dibandingkan dengan implementasi metode ini menggunakan ekspresi LINQ, khususnya melalui parameter jenis Expression<Func<T>> alih-alih parameter status dan panggilan balik, peningkatan performa yang dapat dicapai dengan cara ini benar-benar signifikan. Secara khusus, versi ini ~ 200x lebih cepat daripada yang menggunakan ekspresi LINQ, dan tidak membuat alokasi memori sama sekali.
Menangani Task<T> properti
Jika sebuah properti adalah Task, maka peristiwa notifikasi juga perlu dipicu setelah tugas selesai dijalankan, agar binding diperbarui pada waktu yang tepat. Misalnya, untuk menampilkan indikator pemuatan atau informasi status lainnya untuk operasi yang direpresentasikan oleh tugas tersebut.
ObservableObject memiliki API untuk skenario ini:
public class MyModel : ObservableObject
{
private TaskNotifier<int>? requestTask;
public Task<int>? RequestTask
{
get => requestTask;
set => SetPropertyAndNotifyOnCompletion(ref requestTask, value);
}
public void RequestValue()
{
RequestTask = WebService.LoadMyValueAsync();
}
}
SetPropertyAndNotifyOnCompletion<T>(ref TaskNotifier<T>, Task<T>, string) Di sini metode akan mengurus pembaruan bidang target, memantau tugas baru, jika ada, dan menaikkan peristiwa pemberitahuan ketika tugas tersebut selesai. Dengan demikian, Anda cukup mengikatkan ke properti tugas dan mendapat notifikasi saat statusnya berubah.
TaskNotifier<T> adalah jenis khusus yang diekspos oleh ObservableObject yang membungkus instans target Task<T> dan memungkinkan logika pemberitahuan yang diperlukan untuk metode ini. Tipe TaskNotifier juga dapat digunakan secara langsung jika Anda hanya memiliki Task umum.
Catatan
Metode SetPropertyAndNotifyOnCompletion ini dimaksudkan untuk mengganti penggunaan jenis NotifyTaskCompletion<T> dari Microsoft.Toolkit paket. Jika tipe ini digunakan, tipe ini dapat diganti dengan hanya menggunakan properti internal Task (atau Task<TResult>), lalu metode SetPropertyAndNotifyOnCompletion dapat digunakan untuk menetapkan nilainya dan memicu notifikasi perubahan. Semua properti yang diekspos oleh tipe NotifyTaskCompletion<T> tersedia langsung pada instans Task.
Contoh
- Lihat contoh aplikasi (untuk beberapa kerangka kerja UI) untuk melihat Toolkit MVVM beraksi.
- Anda juga dapat menemukan lebih banyak contoh dalam uji unit.
MVVM Toolkit