ObservableObject
ObservableObject
, ve INotifyPropertyChanging
arabirimleri uygulanarak INotifyPropertyChanged
gözlemlenebilen nesneler için bir temel sınıftır. Özellik değişikliği bildirimlerini desteklemesi gereken her tür nesne için başlangıç noktası olarak kullanılabilir.
Platform API'leri:
ObservableObject
,TaskNotifier
,TaskNotifier<T>
ObservableObject
aşağıdaki ana özelliklere sahiptir:
- ve
INotifyPropertyChanging
içinINotifyPropertyChanged
ve olaylarını kullanıma sunanPropertyChanged
PropertyChanging
temel bir uygulama sağlar. - 'den
ObservableObject
devralan türlerden özellik değerlerini kolayca ayarlamak ve uygun olayları otomatik olarak oluşturmak için kullanılabilecek bir diziSetProperty
yöntem sağlar. - Ancak atanan görevler tamamlandığında özellikleri ayarlama ve bildirim olaylarını otomatik olarak tetikleyebilme
Task
özelliğine sahip yöntemiSetProperty
sağlarSetPropertyAndNotifyOnCompletion
. - Bildirim olaylarının
OnPropertyChanged
nasıl tetiklendiğini özelleştirmek için türetilmiş türlerde geçersiz kılınabilen veOnPropertyChanging
yöntemlerini kullanıma sunar.
Özel bir özelliğe bildirim desteği uygulama örneği aşağıda verilmiştir:
public class User : ObservableObject
{
private string name;
public string Name
{
get => name;
set => SetProperty(ref name, value);
}
}
Sağlanan SetProperty<T>(ref T, T, string)
yöntem özelliğin geçerli değerini denetler ve farklıysa güncelleştirir ve ardından ilgili olayları otomatik olarak yükseltir. Özellik adı özniteliğinin kullanımıyla otomatik olarak yakalanır, bu nedenle hangi özelliğin [CallerMemberName]
güncelleştirileceğini el ile belirtmenize gerek yoktur.
Örneğin veritabanı öğeleriyle çalışırken yaygın bir senaryo, veritabanı modelinin özelliklerini aktaran ve gerektiğinde özellik değişikliği bildirimlerini yükselten bir sarmalama "bağlanabilir" modeli oluşturmaktır. Bu, arabirimi uygulamayan INotifyPropertyChanged
modellere bildirim desteği eklemek istediğinizde de gereklidir. ObservableObject
bu işlemi daha basit hale getirmek için ayrılmış bir yöntem sağlar. Aşağıdaki örnekte, User
öğesinden ObservableObject
devralmadan veritabanı tablosunu doğrudan eşleyen bir model verilmiştir:
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);
}
}
Bu durumda aşırı yüklemeyi kullanıyoruz SetProperty<TModel, T>(T, T, TModel, Action<TModel, T>, string)
. İmza öncekinden biraz daha karmaşıktır. Bu, önceki senaryoda olduğu gibi bir yedekleme alanına erişimimiz olmasa bile kodun son derece verimli olmasına izin vermek için gereklidir. Farklı bileşenlerin rolünü anlamak için bu yöntem imzasının her bir bölümünü ayrıntılı olarak inceleyebiliriz:
TModel
, sarmaladığımız modelin türünü gösteren bir tür bağımsız değişkenidir. Bu durumda, bizim sınıfımızUser
olacak. Bunu açıkça belirtmemiz gerekmeyen C# derleyicisi yöntemi nasıl çağırdığımızaSetProperty
göre bunu otomatik olarak çıkaracaktır.T
, ayarlamak istediğimiz özelliğin türüdür. benzer şekildeTModel
, bu da otomatik olarak çıkarılır.T oldValue
ilk parametredir ve bu durumda sarmaladığımız özelliğin geçerli değerini geçirmek için kullanıyoruzuser.Name
.T newValue
özelliğine ayarlanacağı yeni değerdir ve burada özellik ayarlayıcısı içindeki giriş değeri olan değerini geçiriyoruzvalue
.TModel model
sarmaladığımız hedef modeldir, bu örnekte alandauser
depolanan örneği geçiriyoruz.Action<TModel, T> callback
özelliğin yeni değeri geçerli değerden farklıysa ve özelliğin ayarlanması gerekiyorsa çağrılacak bir işlevdir. Bu, hedef modeli ve ayarlanacak yeni özellik değerini girdi olarak alan bu geri çağırma işlevi tarafından yapılır. Bu durumda yalnızca giriş değerini (bunu çağırdıkn
) özelliğineName
(yaparaku.Name = n
) atıyoruz. C# derleyicisinin geri çağırma işlevini önbelleğe alıp bir dizi performans iyileştirmesi gerçekleştirmesine olanak tanıdığından, geçerli kapsamdaki değerleri yakalamaktan kaçınmak ve yalnızca geri çağırmaya giriş olarak verilenlerle etkileşimde bulunabilmek burada önemlidir. Bunun nedeni yalnızca buradaki alana veya ayarlayıcıdaki parametreyevalue
doğrudan erişmemizuser
değil, bunun yerine yalnızca lambda ifadesi için giriş parametrelerini kullanmamızdır.
SetProperty<TModel, T>(T, T, TModel, Action<TModel, T>, string)
yöntemi, son derece kompakt bir API sağlarken hem alma hem de hedef özellikleri ayarlamayı üstlenirken bu sarmalama özelliklerinin oluşturulmasını son derece basit hale getirir.
Not
LinQ ifadeleri kullanılarak, özellikle durum ve geri çağırma parametreleri yerine tür Expression<Func<T>>
parametresi aracılığıyla bu yöntemin uygulanmasıyla karşılaştırıldığında, bu şekilde elde edilebilecek performans geliştirmeleri gerçekten önemlidir. Özellikle, bu sürüm LINQ ifadelerini kullanandan yaklaşık 200 kat daha hızlıdır ve hiç bellek ayırması yapmaz.
Özellik bir Task
özellikse, bağlamaların doğru zamanda güncelleştirilmesi için görev tamamlandıktan sonra bildirim olayının da tetiklenmesi gerekir. Örneğin, görev tarafından temsil edilen işlemle ilgili bir yükleme göstergesi veya diğer durum bilgilerini görüntülemek için. ObservableObject
bu senaryo için bir API'ye sahiptir:
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)
Burada yöntem hedef alanı güncelleştirme, varsa yeni görevi izleme ve görev tamamlandığında bildirim olayını başlatma ile ilgilenir. Bu şekilde, bir görev özelliğine bağlanmak ve durumu değiştiğinde bildirim almak mümkündür. TaskNotifier<T>
, tarafından ObservableObject
kullanıma sunulan ve bir hedef Task<T>
örneği sarmalayan ve bu yöntem için gerekli bildirim mantığını etkinleştiren özel bir türüdür. Yalnızca TaskNotifier
genel Task
bir türünüz varsa, türü doğrudan da kullanabilirsiniz.
Not
SetPropertyAndNotifyOnCompletion
yöntemi, paketten Microsoft.Toolkit
tür kullanımını NotifyTaskCompletion<T>
değiştirmek için amaçlanır. Bu tür kullanılıyorsa, yalnızca iç Task
(veya Task<TResult>
) özelliğiyle değiştirilebilir ve ardından SetPropertyAndNotifyOnCompletion
değerini ayarlamak ve bildirim değişikliklerini yükseltmek için yöntemi kullanılabilir. Türü tarafından NotifyTaskCompletion<T>
sunulan tüm özellikler doğrudan örneklerde Task
kullanılabilir.
- MVVM Araç Seti'ni uygulamada görmek için örnek uygulamaya (birden çok UI çerçevesi için) göz atın.
- Birim testlerinde daha fazla örnek de bulabilirsiniz.
MVVM Toolkit geri bildirimi
MVVM Toolkit, açık kaynak bir projedir. Geri bildirim sağlamak için bir bağlantı seçin: