Priorita hodnoty vlastnosti závislosti (WPF .NET)

Práce systému vlastností Windows Presentation Foundation (WPF) ovlivňují hodnotu vlastnosti závislosti. Tento článek vysvětluje, jak přednost různých vstupů založených na vlastnostech v rámci systému vlastností WPF určuje efektivní hodnotu vlastnosti závislosti.

Důležité

Dokumentace k desktopové příručce pro .NET 7 a .NET 6 se právě připravuje.

Předpoklady

V článku se předpokládá základní znalost vlastností závislostí a že jste si přečetli přehled vlastností závislostí. Pokud chcete postupovat podle příkladů v tomto článku, pomůže vám to, pokud znáte jazyk XAML (Extensible Application Markup Language) a víte, jak psát aplikace WPF.

Systém vlastností WPF

Systém vlastností WPF používá k určení hodnoty vlastností závislostí, jako je ověření vlastností v reálném čase, pozdní vazba a oznámení o změnách vlastností souvisejících vlastností. Přestože pořadí a logika používané k určení hodnot vlastností závislostí jsou složité, učení vám může pomoct vyhnout se zbytečným nastavením vlastností a také zjistit, proč pokus o nastavení vlastnosti závislosti nezpůsobí očekávanou hodnotu.

Vlastnosti závislostí nastavené na více místech

Následující příklad XAML ukazuje, jak můžou ovlivnit tři různé operace set u vlastnosti tlačítka Background .

<StackPanel>
    <StackPanel.Resources>
        <ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type Button}">
            <Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" 
                    BorderBrush="{TemplateBinding BorderBrush}">
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
            </Border>
        </ControlTemplate>
    </StackPanel.Resources>

    <Button Template="{StaticResource ButtonTemplate}" Background="Red">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Background" Value="Blue"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="Yellow" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
        Which color do you expect?
    </Button>
</StackPanel>

V příkladu Background je vlastnost místně nastavena na Red. Implicitní styl deklarovaný v oboru tlačítka se však pokusí nastavit Background vlastnost na Blue. A když je myš nad tlačítkem, trigger v implicitního stylu se pokusí nastavit Background vlastnost na Yellow. S výjimkou převodu a animace má místně nastavená hodnota vlastnosti nejvyšší prioritu, takže tlačítko bude červené – i při najetí myší. Pokud ale z tlačítka odeberete místně nastavenou hodnotu, získá její Background hodnotu ze stylu. Ve stylu mají triggery přednost, takže tlačítko bude žluté při najetí myší a v opačném případě modré. Příklad nahradí výchozí hodnotu ControlTemplate tlačítka, protože výchozí šablona má pevně zakódovanou hodnotu myši Background .

Seznam priorit vlastností závislostí

Následující seznam je konečným pořadím priority, které systém vlastností používá při přiřazování hodnot modulu runtime k vlastnostem závislosti. Nejvyšší priorita je uvedena jako první.

  1. Převod systému vlastností. Další informace o převodu naleznete v tématu Převod a animace.

  2. Aktivní animace nebo animace s chováním přidržet Pokud chcete mít praktický efekt, musí mít animační hodnota přednost před základní (neanimovanou) hodnotou, i když byla základní hodnota nastavena místně. Další informace najdete v tématu Převod a animace.

  3. Místní hodnoty. Místní hodnotu můžete nastavit prostřednictvím vlastnosti "obálka", která odpovídá nastavení atributu nebo elementu vlastnosti v XAML nebo voláním SetValue rozhraní API pomocí vlastnosti konkrétní instance. Místní hodnota nastavená prostřednictvím vazby nebo prostředku bude mít stejnou prioritu jako hodnota, která je přímo nastavená.

  4. Hodnoty vlastností šablony TemplatedParent Prvek obsahuje TemplatedParent , pokud byl vytvořen šablonou (ControlTemplate nebo DataTemplate). Další informace naleznete v tématu TemplatedParent. Pořadí priorit v šabloně určené v TemplatedParentšabloně je:

    1. Aktivační události.

    2. Sady vlastností, obvykle prostřednictvím atributů XAML.

  5. Implicitní styly Platí pouze pro Style vlastnost. Hodnota Style je jakýkoli prostředek stylu s TargetType hodnotou, která odpovídá typu elementu. Prostředek stylu musí existovat v rámci stránky nebo aplikace. Vyhledávání prostředku implicitního stylu se nevztahuje na prostředky stylů v motivech.

  6. Aktivační události stylu Trigger stylu je trigger v rámci explicitního nebo implicitního stylu. Styl musí existovat v rámci stránky nebo aplikace. Triggery ve výchozím stylu mají nižší prioritu.

  7. Triggery šablon Trigger šablony je trigger z přímo použité šablony nebo ze šablony ve stylu. Styl musí existovat v rámci stránky nebo aplikace.

  8. Hodnoty setter stylu. Hodnota setter stylu je hodnota použitá Setter v rámci stylu. Styl musí existovat v rámci stránky nebo aplikace.

  9. Výchozí styly, označované také jako styly motivu. Další informace naleznete v tématu Výchozí styly (Motiv). Ve výchozím stylu je pořadí priorit:

    1. Aktivní triggery.

    2. Nastavení.

  10. Dědičnost. Některé vlastnosti závislosti podřízeného elementu dědí jejich hodnotu z nadřazeného elementu. Proto nemusí být nutné nastavit hodnoty vlastností pro každý prvek v celé aplikaci. Další informace naleznete v tématu Dědičnost hodnot vlastností.

  11. Výchozí hodnota z metadat vlastností závislosti A vlastnost závislosti může mít výchozí hodnotu nastavenou během registrace systému vlastností této vlastnosti. Odvozené třídy, které dědí vlastnost závislosti, mohou přepsat metadata vlastnosti závislosti (včetně výchozí hodnoty) na základě jednotlivých typů. Další informace naleznete v tématu Metadata vlastností závislostí. U zděděné vlastnosti má výchozí hodnota nadřazeného prvku přednost před výchozí hodnotou podřízeného prvku. Pokud tedy není nastavena zděděná vlastnost, použije se výchozí hodnota kořenového nebo nadřazeného prvku místo výchozí hodnoty podřízeného prvku.

TemplatedParent

TemplatedParent priorita se nevztahuje na vlastnosti prvků, které jsou deklarovány přímo ve standardním kódu aplikace. Koncept TemplatedParent existuje pouze pro podřízené položky ve vizuálním stromu, které přicházejí do existence prostřednictvím aplikace šablony. Když systém vlastností prohledá šablonu určenou TemplatedParent pro hodnoty vlastnosti elementu, prohledává šablonu, která vytvořila prvek. Hodnoty vlastností ze TemplatedParent šablony obecně fungují, jako by byly místně nastavené hodnoty prvku, ale s menší prioritou než skutečné místní hodnoty, protože šablony jsou potenciálně sdíleny. Další informace najdete na webu TemplatedParent.

The Style vlastnost

Stejné pořadí priorit platí pro všechny vlastnosti závislosti s výjimkou Style vlastnosti. Vlastnost Style je jedinečná v tom, že nemůže být sama o sobě stylována. Vynucení nebo animace Style vlastnosti se nedoporučuje (a animování Style vlastnosti by vyžadovalo vlastní třídu animace). V důsledku toho se nepoužijí všechny položky priority. Vlastnost lze nastavit Style pouze třemi způsoby:

  • Explicitní styl Vlastnost Style elementu je nastavena přímo. Hodnota Style vlastnosti funguje jako místní hodnota a má stejnou prioritu jako položka 3 v seznamu priorit. Ve většině scénářů nejsou explicitní styly definovány jako vložené a místo toho jsou explicitně odkazovány jako prostředek, například Style="{StaticResource myResourceKey}".

  • Implicitní styl Style Vlastnost elementu není nastavena přímo. Místo toho se styl použije, pokud existuje na určité úrovni v rámci stránky nebo aplikace, a má klíč prostředku, který odpovídá typu prvku, na který se styl vztahuje, například <Style TargetType="x:Type Button">. Typ se musí přesně shodovat, například <Style TargetType="x:Type Button"> se nepoužije na MyButton typ, i když MyButton je odvozen z Button. Hodnota Style vlastnosti má stejnou prioritu jako položka 5 v seznamu priorit. Implicitní hodnotu stylu lze zjistit voláním DependencyPropertyHelper.GetValueSource metody, předáním Style vlastnosti a kontrolou ImplicitStyleReference výsledků.

  • Výchozí styl, označovaný také jako styl motivu. Style Vlastnost elementu není nastavena přímo. Místo toho pochází z vyhodnocení motivu modulu runtime prezentačním modulem WPF. Před modulem Style runtime je nullhodnota vlastnosti . Hodnota Style vlastnosti má stejnou prioritu jako položka 9 v seznamu priorit.

Výchozí styly (motiv)

Každý ovládací prvek, který je součástí WPF, má výchozí styl, který se může lišit podle motivu, což je důvod, proč se výchozí styl někdy označuje jako styl motivu.

Jedná se ControlTemplate o důležitou položku ve výchozím stylu ovládacího prvku. ControlTemplate je hodnota setter vlastnosti stylu Template . Pokud výchozí styly šablonu neobsahují, ovládací prvek bez vlastní šablony v rámci vlastního stylu nebude mít žádný vizuální vzhled. Šablona nejen definuje vizuální vzhled ovládacího prvku, ale také definuje propojení mezi vlastnostmi ve vizuálním stromu šablony a odpovídající třídou ovládacího prvku. Každý ovládací prvek zveřejňuje sadu vlastností, které mohou ovlivnit vzhled ovládacího prvku bez nahrazení šablony. Představte si například výchozí vzhled Thumb ovládacího prvku, což je ScrollBar součást.

Ovládací Thumb prvek má určité přizpůsobitelné vlastnosti. Výchozí šablona Thumb ovládacího prvku vytvoří základní strukturu nebo strom vizuálu s několika vnořenými Border komponentami, které vytvoří zkosený vzhled. V šabloně jsou vlastnosti, které mají být přizpůsobitelné Thumb třídou, zpřístupněny prostřednictvím TemplateBinding. Výchozí šablona Thumb ovládacího prvku má různé vlastnosti ohraničení, které sdílejí vazbu šablony s vlastnostmi, jako Background jsou nebo BorderThickness. Pokud jsou ale hodnoty vlastností nebo vizuálních uspořádání pevně zakódované v šabloně nebo jsou vázané na hodnoty, které pocházejí přímo z motivu, můžete tyto hodnoty změnit pouze nahrazením celé šablony. Obecně platí, že pokud vlastnost pochází ze šablony nadřazeného objektu a není vystavena objektem TemplateBinding, nelze hodnotu vlastnosti změnit styly, protože neexistuje žádný pohodlný způsob, jak ji cílit. Tato vlastnost ale může být stále ovlivněna dědičností hodnot vlastností v použité šabloně nebo výchozí hodnotou.

Výchozí styly určují TargetType v jejich definicích. Vyhodnocení motivu modulu runtime odpovídá TargetType výchozímu DefaultStyleKey stylu vlastnosti ovládacího prvku. Naproti tomu chování vyhledávání implicitních stylů používá skutečný typ ovládacího prvku. Hodnota DefaultStyleKey je zděděna odvozenými třídami, takže odvozené prvky, které by jinak neměly žádný přidružený styl získat výchozí vzhled vizuálu. Pokud například odvozujete MyButtonButton, MyButton zdědí výchozí šablonu Button. Odvozené třídy mohou přepsat výchozí hodnotu DefaultStyleKey v metadatech vlastností závislostí. Pokud tedy chcete použít jinou vizuální reprezentaci MyButton, můžete přepsat metadata vlastností závislostí pro DefaultStyleKey zapnuto MyButtona pak definovat příslušný výchozí styl včetně šablony, kterou zabalíte pomocí MyButton ovládacího prvku. Další informace najdete v tématu Přehled vytváření obsahu ovládacích prvků.

Dynamický prostředek

Dynamické odkazy na prostředky a operace vazby mají přednost před umístěním, ve kterém jsou nastavené. Například dynamický prostředek použitý na místní hodnotu má stejnou prioritu jako položka 3 v seznamu priorit. V dalším příkladu má dynamická vazba prostředků použitá na setter vlastnosti v rámci výchozího stylu stejnou prioritu jako položka 9 v seznamu priorit. Vzhledem k tomu, že dynamické odkazy na prostředky a vazby musí získat hodnoty ze stavu modulu runtime aplikace, proces určení priority hodnoty vlastnosti pro libovolnou danou vlastnost se rozšíří do modulu runtime.

Dynamické odkazy na prostředky nejsou technicky součástí systému vlastností a mají vlastní pořadí vyhledávání, které komunikuje se seznamem priorit. V podstatě je prioritou dynamických odkazů na prostředky: element na kořen stránky, aplikace, motiv a pak systém. Další informace najdete v tématu Prostředky XAML.

I když mají dynamické odkazy na prostředky a vazby přednost umístění, ve kterém jsou nastavené, hodnota se odloží. Jedním z důsledků je to, že pokud nastavíte dynamický prostředek nebo vazbu na místní hodnotu, všechny změny místní hodnoty zcela nahradí dynamický prostředek nebo vazbu. I když zavoláte metodu ClearValue , která vymaže hodnotu místně nastavené, dynamický prostředek nebo vazba se neobnoví. Ve skutečnosti, pokud voláte ClearValue vlastnost, která má dynamický prostředek nebo vazbu (bez literálové místní hodnoty), dynamický prostředek nebo vazba se vymaže.

SetCurrentValue

Metoda SetCurrentValue je dalším způsobem, jak nastavit vlastnost, ale není v seznamu priorit. SetCurrentValue umožňuje změnit hodnotu vlastnosti bez přepsání zdroje předchozí hodnoty. Pokud je například vlastnost nastavena triggerem a pak přiřadíte jinou hodnotu pomocí SetCurrentValue, další aktivační akce nastaví vlastnost zpět na hodnotu aktivační události. Kdykoli chcete nastavit hodnotu vlastnosti, aniž byste této hodnotě dali úroveň priority místní hodnoty, můžete ji použít SetCurrentValue . Podobně můžete použít SetCurrentValue ke změně hodnoty vlastnosti bez přepsání vazby.

Převod a animace

Převod i animace fungují na základní hodnotě. Základní hodnota je hodnota vlastnosti závislosti s nejvyšší prioritou určenou vyhodnocením seznamu priorit směrem nahoru až do dosažení položky 2.

Pokud animace nezadává hodnoty vlastností FromTo pro určité chování nebo pokud se animace po dokončení záměrně vrátí k základní hodnotě, může základní hodnota ovlivnit animaci. Pokud to chcete vidět v praxi, spusťte ukázkovou aplikaci Cílové hodnoty . V ukázce zkuste pro výšku obdélníku nastavit počáteční místní hodnoty, které se liší od jakékoli From hodnoty. Ukázkové animace začínají hned tím, že From místo základní hodnoty použijete hodnotu. Zadáním parametru StopFillBehavior, při dokončení animace resetuje hodnotu vlastnosti na její základní hodnotu. Normální priorita se používá pro stanovení základní hodnoty po skončení animace.

U jedné vlastnosti lze použít více animací, přičemž každá animace má jinou prioritu. Místo použití animace s nejvyšší prioritou může prezentační modul WPF složeného hodnoty animací v závislosti na způsobu definování animací a typu animovaných hodnot. Další informace najdete v přehledu animace.

Převod je v horní části seznamu priorit. I spuštěná animace podléhá převodu hodnot. Některé existující vlastnosti závislostí ve WPF mají integrovaný převod. U vlastních vlastností závislostí můžete definovat chování převodu zápisem CoerceValueCallback , který předáte jako součást metadat při vytváření vlastnosti. Můžete také přepsat chování převodu existujících vlastností přepsáním metadat pro tuto vlastnost v odvozené třídě. Převod interaguje se základní hodnotou takovým způsobem, že se omezení při převodu použijí tak, jak existují v době, ale základní hodnota je stále zachována. V důsledku toho, pokud jsou omezení v převodu později zrušena, bude převod vrátit nejbližší možnou hodnotu základní hodnotě a potenciálně vliv na převod na vlastnost přestane, jakmile budou všechna omezení zrušena. Další informace o chování při převodu naleznete v tématu Zpětné volání a ověřování vlastností závislostí.

Chování triggerů

Ovládací prvky často definují chování triggerů jako součást jejich výchozího stylu. Nastavení místních vlastností u ovládacích prvků může potenciálně kolidovat s těmito triggery, což brání aktivačním událostem (vizuálně nebo chování) na události řízené uživatelem. Běžným použitím triggeru vlastnosti je řízení vlastností stavu, například IsSelected .IsEnabled Například když Button je zakázané, trigger stylu motivu (IsEnabled je false) ve výchozím nastavení nastaví Foreground hodnotu, aby Button se zobrazovala šedě. Pokud jste nastavili místní Foreground hodnotu, bude vyšší hodnota místní vlastnosti přerušovat hodnotu stylu Foreground motivu, i když je zakázaná Button . Při nastavování hodnot vlastností, které přepisují chování aktivační události na úrovni motivu pro ovládací prvek, dávejte pozor, abyste zbytečně nezasahovali do zamýšleného uživatelského prostředí tohoto ovládacího prvku.

ClearValue

Metoda ClearValue vymaže všechny místně použité hodnoty vlastnosti závislosti pro prvek. Volání ClearValue ale nezaručuje, že výchozí hodnota vytvořená v metadatech během registrace vlastnosti je nová efektivní hodnota. Všichni ostatní účastníci v seznamu priorit jsou stále aktivní a odeberou se jenom místně nastavená hodnota. Pokud například zavoláte ClearValue vlastnost, která má styl motivu, použije se hodnota stylu motivu jako nová hodnota místo výchozího nastavení založeného na metadatech. Pokud chcete nastavit hodnotu vlastnosti na výchozí hodnotu registrovaných metadat, získejte výchozí hodnotu metadat dotazováním na metadata vlastnosti závislosti a místně nastavte hodnotu vlastnosti s voláním SetValuena .

Viz také