Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Je ObservableObject základní třídou pro objekty, které jsou pozorovatelné implementací INotifyPropertyChanged a INotifyPropertyChanging rozhraní. Dá se použít jako výchozí bod pro všechny druhy objektů, které potřebují podporovat oznámení o změnách vlastností.
Rozhraní API platformy:
ObservableObject,TaskNotifierTaskNotifier<T>
Jak to funguje
ObservableObject má následující hlavní funkce:
- Poskytuje základní implementaci pro
INotifyPropertyChangedaINotifyPropertyChangingzveřejněníPropertyChangedudálostí aPropertyChangingudálostí. - Poskytuje řadu
SetPropertymetod, které lze použít k snadnému nastavení hodnot vlastností z typů dědění zObservableObjecta k automatickému vyvolání příslušných událostí. - Poskytuje metodu
SetPropertyAndNotifyOnCompletion, která je analogickáSetProperty, ale s možností nastavitTaskvlastnosti a vyvolat události oznámení automaticky při dokončení přiřazených úkolů. - Zveřejňuje
OnPropertyChangedmetody aOnPropertyChangingmetody, které je možné přepsat v odvozených typech a přizpůsobit způsob vyvolání událostí oznámení.
Jednoduchá vlastnost
Tady je příklad implementace podpory oznámení pro vlastní vlastnost:
public class User : ObservableObject
{
private string name;
public string Name
{
get => name;
set => SetProperty(ref name, value);
}
}
Zadaná SetProperty<T>(ref T, T, string) metoda zkontroluje aktuální hodnotu vlastnosti a aktualizuje ji, pokud se liší, a pak také vyvolá příslušné události automaticky. Název vlastnosti se automaticky zaznamenává pomocí atributu [CallerMemberName] , takže není nutné ručně určit, která vlastnost se aktualizuje.
Zabalení nepozorovatelného modelu
Běžným scénářem, například při práci s databázovými položkami, je vytvoření obtékání "bindable" modelu, který předává vlastnosti databázového modelu a v případě potřeby vyvolá oznámení o změně vlastnosti. To je potřeba také v případě, že chcete do modelů vložit podporu oznámení, která rozhraní neimplementují INotifyPropertyChanged . ObservableObject poskytuje vyhrazenou metodu, která usnadňuje tento proces. V následujícím příkladu User je model přímo mapující databázovou tabulku bez dědění z 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);
}
}
V tomto případě používáme SetProperty<TModel, T>(T, T, TModel, Action<TModel, T>, string) přetížení. Podpis je o něco složitější než předchozí – to je nezbytné k tomu, aby byl kód stále velmi efektivní, i když nemáme přístup k záložnímu poli, jako je v předchozím scénáři. Jednotlivé části tohoto podpisu metody můžeme podrobně projít, abychom porozuměli roli různých komponent:
TModelje argument typu označující typ modelu, který zabalíme. V tomto případě to bude našeUsertřída. Všimněte si, že toto explicitní zadání nepotřebujeme – kompilátor jazyka C# to automaticky odvodí tím, jak metoduSetPropertyvyvoláváme.Tje typ vlastnosti, kterou chceme nastavit.TModelPodobně jako , to je odvozeno automaticky.T oldValueje první parametr a v tomto případě používámeuser.Namek předání aktuální hodnoty této vlastnosti, kterou zabalíme.T newValueje nová hodnota nastavená na vlastnost a zde předávámevalue, což je vstupní hodnota v rámci setter vlastnosti.TModel modelje cílový model, který zabalíme, v tomto případě předáváme instanci uloženouuserv poli.Action<TModel, T> callbackje funkce, která se vyvolá, pokud se nová hodnota vlastnosti liší od aktuální hodnoty a vlastnost musí být nastavena. To provede tato funkce zpětného volání, která přijímá jako vstup cílový model a novou hodnotu vlastnosti, která se má nastavit. V tomto případě pouze přiřazujeme vstupní hodnotu (kterou jsme volalin) vlastnostiName(tím).u.Name = nJe důležité se zde vyhnout zachycení hodnot z aktuálního oboru a pracovat pouze s hodnotami zadanými jako vstup pro zpětné volání, protože to umožňuje kompilátoru jazyka C# ukládat funkci zpětného volání do mezipaměti a provádět řadu vylepšení výkonu. Důvodem je to, že k poli tadyvaluenebo parametru v setteru nemáme jen přímý přístupuser, ale místo toho používáme jenom vstupní parametry pro výraz lambda.
Metoda SetProperty<TModel, T>(T, T, TModel, Action<TModel, T>, string) vytváří tyto vlastnosti obtékání velmi jednoduché, protože se postará o načtení a nastavení cílových vlastností při poskytování extrémně kompaktního rozhraní API.
Poznámka:
Ve srovnání s implementací této metody pomocí výrazů LINQ, konkrétně prostřednictvím parametru typu Expression<Func<T>> místo parametrů stavu a zpětného volání, zlepšení výkonu, které lze dosáhnout tímto způsobem, jsou opravdu významné. Konkrétně je tato verze ~200x rychlejší než ta, která používá výrazy LINQ, a neuvádí vůbec žádné přidělení paměti.
Zpracování Task<T> vlastností
Je-li vlastnost Task také nutné vyvolat událost oznámení po dokončení úkolu, aby byly vazby aktualizovány ve správný čas. Např. zobrazení indikátoru načítání nebo jiné informace o stavu operace reprezentované úkolem. ObservableObject má rozhraní API pro tento scénář:
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) Zde se metoda postará o aktualizaci cílového pole, monitorování nového úkolu, pokud je k dispozici, a vyvolání události oznámení po dokončení úkolu. Tímto způsobem je možné vytvořit vazbu na vlastnost úkolu a upozornit na změny stavu. Jedná se TaskNotifier<T> o speciální typ vystavený ObservableObject tím, že zabalí cílovou Task<T> instanci a povolí potřebnou logiku oznámení pro tuto metodu. Typ TaskNotifier je také k dispozici přímo, pokud máte pouze obecný Task .
Poznámka:
Metoda SetPropertyAndNotifyOnCompletion je určena k nahrazení použití NotifyTaskCompletion<T> typu z Microsoft.Toolkit balíčku. Pokud byl tento typ použit, může být nahrazen pouze vnitřní Task (nebo Task<TResult>) vlastnost, a pak lze metodu SetPropertyAndNotifyOnCompletion použít k nastavení jeho hodnoty a vyvolat změny oznámení. Všechny vlastnosti vystavené typem NotifyTaskCompletion<T> jsou k dispozici přímo na Task instancích.
Příklady
- Podívejte se na ukázkovou aplikaci (pro více architektur uživatelského rozhraní) a podívejte se na sadu nástrojů MVVM v akci.
- Další příklady najdete také v testech jednotek.