Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A ObservableObject az olyan objektumok alaposztálya, amelyek a INotifyPropertyChanged és INotifyPropertyChanging interfészek implementálásával megfigyelhetők. Kiindulópontként használható minden olyan objektumhoz, amelyeknek támogatniuk kell a tulajdonságmódosítási értesítéseket.
Platform API-k:
ObservableObject,TaskNotifier,TaskNotifier<T>
Hogyan működik?
ObservableObject a következő fő funkciókkal rendelkezik:
- Alapszintű megvalósítást biztosít a(z)
INotifyPropertyChangedésINotifyPropertyChangingszámára, elérhetővé téve a(z)PropertyChangedésPropertyChangingeseményeket. -
SetPropertymetódusok sorát biztosítja, amelyekkel egyszerűen beállíthatók aObservableObject-ből származó típusok tulajdonságainak értékei, és automatikusan kiválthatók a megfelelő események. - Biztosítja a
SetPropertyAndNotifyOnCompletionmetódust, amely aSetPropertymetódushoz hasonló, de lehetővé teszi aTasktulajdonságok beállítását, valamint az értesítési események automatikus kiváltását a hozzárendelt feladatok befejezésekor. - Elérhetővé teszi azokat a
OnPropertyChangedmódszereket ésOnPropertyChangingmódszereket, amelyek származtatott típusokban felülírhatók az értesítési események létrehozásának testreszabásához.
Egyszerű tulajdonság
Íme egy példa arra, hogyan valósíthat meg értesítési támogatást egy egyéni tulajdonsághoz:
public class User : ObservableObject
{
private string name;
public string Name
{
get => name;
set => SetProperty(ref name, value);
}
}
A megadott SetProperty<T>(ref T, T, string) módszer ellenőrzi a tulajdonság aktuális értékét, és frissíti, ha eltér, majd automatikusan növeli a releváns eseményeket. A rendszer automatikusan rögzíti a tulajdonság nevét az [CallerMemberName] attribútum használatával, így nem kell manuálisan megadni, hogy melyik tulajdonság frissül.
Egy nem megfigyelhető modell burkolása
Gyakori forgatókönyv például az adatbáziselemek használata során, hogy létrehoz egy burkoló "kötésre alkalmas" modellt, amely továbbítja az adatbázismodell tulajdonságait, és szükség esetén megjeleníti a tulajdonság által módosított értesítéseket. Erre akkor is szükség van, ha az értesítési támogatást olyan modellekre szeretné injektálni, amelyek nem implementálják a INotifyPropertyChanged felületet.
ObservableObject dedikált módszert biztosít a folyamat egyszerűbbé javítására. A következő példában a User egy olyan modell, amely közvetlenül egy adatbázistáblához van rendelve, és nem öröklődik a ObservableObject osztályból:
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);
}
}
Ebben az esetben a SetProperty<TModel, T>(T, T, TModel, Action<TModel, T>, string) túlterhelést használjuk. Az aláírás valamivel összetettebb, mint az előző – ez azért szükséges, hogy a kód még akkor is rendkívül hatékony legyen, ha nem férünk hozzá egy háttérmezőhöz, mint az előző forgatókönyvben. A metódus aláírásának egyes részeit részletesen áttekinthetjük a különböző összetevők szerepének megértéséhez:
-
TModelegy típusargumentum, amely a burkoló modell típusát jelzi. Ebben az esetben ez lesz aUserosztályunk. Vegye figyelembe, hogy ezt nem kell explicit módon megadni – a C#-fordító ezt automatikusan a metódus meghívásával fogja következtetniSetProperty. -
Ta beállítani kívánt tulajdonság típusa. ATModel-hoz hasonlóan ez automatikusan következtethető ki. -
T oldValueaz első paraméter, és ebben az esetben auser.Nameelemet használjuk az általunk becsomagolt tulajdonság aktuális értékének átadására. -
T newValueaz új érték, amelyet a tulajdonsághoz kell beállítani, és itt adjuk átvalue, amely a tulajdonság-beállító bemeneti értéke. -
TModel modelAz a célmodell, amelyet körbefuttatunk, ebben az esetben a mezőben tároltuserpéldányt adjuk át. -
Action<TModel, T> callbackegy függvény, amelyet akkor hív meg a rendszer, ha a tulajdonság új értéke eltér az aktuálistól, és a tulajdonságot be kell állítani. Ezt a visszahívási függvény fogja elvégezni, amely bemenetként fogadja a célmodellt és a beállítandó új tulajdonságértéket. Ebben az esetben egyszerűen a bemeneti értéket (amelyetn-nak neveztünk) rendeljük aNametulajdonsághoz (úgy, hogyu.Name = n). Itt fontos, hogy ne rögzítsük az aktuális hatókör értékeit, és csak a visszahívás bemeneteként megadott értékekkel kommunikáljon, mivel így a C#-fordító gyorsítótárazza a visszahívási függvényt, és számos teljesítménybeli fejlesztést hajthat végre. Ennek az az oka, hogy nem csak közvetlenül érjük el ausermezőt itt, vagy avalueparamétert a beállítóban, hanem csak a lambda kifejezés bemeneti paramétereit használjuk.
A SetProperty<TModel, T>(T, T, TModel, Action<TModel, T>, string) módszer rendkívül egyszerűvé teszi ezeket a burkoló tulajdonságokat, mivel gondoskodik a céltulajdonságok lekéréséről és beállításáról, miközben rendkívül kompakt API-t biztosít.
Note
Ahhoz képest, hogy ez a módszer LINQ-kifejezéseket használ, konkrétan egy típusparaméteren Expression<Func<T>> keresztül az állapot- és visszahívási paraméterek helyett, az így elérhető teljesítménybeli fejlesztések valóban jelentősek. Ez a verzió különösen ~200-szor gyorsabb, mint a LINQ-kifejezéseket használó verzió, és egyáltalán nem végez memórialefoglalást.
Tulajdonságok kezelése Task<T>
Ha egy tulajdonság egy Task tulajdonság, akkor a tevékenység befejezése után az értesítési eseményt is fel kell emelni, hogy a kötések a megfelelő időben frissüljenek. Például egy betöltési jelző vagy más állapotinformáció megjelenítéséhez a tevékenység által képviselt műveleten.
ObservableObject ehhez a forgatókönyvhöz rendelkezik API-val:
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();
}
}
Itt a SetPropertyAndNotifyOnCompletion<T>(ref TaskNotifier<T>, Task<T>, string) metódus gondoskodik a célmező frissítéséről, az új tevékenység figyeléséről, ha van ilyen, és az értesítési eseményt az adott tevékenység befejezésekor emeli. Így egyszerűen kapcsolódhat egy tevékenységtulajdonsághoz, és értesítést kaphat az állapotváltozásokról. A TaskNotifier<T> egy speciális típus, amelyet a ObservableObject tesz elérhetővé, amely egy cél Task<T>-példányt burkol be, és lehetővé teszi az ehhez a metódushoz szükséges értesítési logikát. A TaskNotifier típus közvetlenül is használható, ha csak általános Task típussal rendelkezik.
Note
A SetPropertyAndNotifyOnCompletion metódus a NotifyTaskCompletion<T> típus használatát hivatott lecserélni a Microsoft.Toolkit csomagból. Ha ezt a típust használták, csak a belső Task (vagy Task<TResult>) tulajdonsággal helyettesíthető, majd a SetPropertyAndNotifyOnCompletion metódussal beállíthatja az értékét, és értesítési módosításokat hajthat végre. A(z) NotifyTaskCompletion<T> típus által elérhetővé tett összes tulajdonság közvetlenül elérhető a(z) Task példányokon.
Examples
- Tekintse meg a mintaalkalmazást (több felhasználói felületi keretrendszer esetén) az MVVM-eszközkészlet működés közbeni megtekintéséhez.
- Az egységtesztekben további példákat is találhat.