Sdílet prostřednictvím


Přehled vlastností závislostí

Windows Presentation Foundation (WPF) poskytuje sadu služeb, které lze použít k rozšíření funkčnosti vlastnosti typu . Společně se tyto služby označují jako systém vlastností WPF. Vlastnost, která je podporována systémem vlastností WPF, se označuje jako vlastnost závislosti. Tento přehled popisuje systém vlastností WPF a možnosti vlastnosti závislosti, včetně toho, jak používat existující vlastnosti závislostí v XAML a v kódu. Tento přehled také představuje specializované aspekty vlastností závislostí, jako jsou metadata vlastností závislostí a jak vytvořit vlastní vlastnost závislostí ve vlastní třídě.

Požadavky

Tento článek předpokládá základní znalosti systému typů .NET a objektově orientovaného programování. Pokud chcete postupovat podle příkladů v tomto článku, pomůže vám pochopit XAML a vědět, jak psát aplikace WPF. Další informace najdete v tématu Kurz: Vytvoření nové aplikace WPF pomocí .NET.

Vlastnosti závislostí a vlastnosti CLR

Vlastnosti WPF jsou obvykle vystaveny jako standardní vlastnosti .NET. S těmito vlastnostmi můžete pracovat na základní úrovni a nikdy nevíte, že jsou implementované jako vlastnost závislosti. Znalost některých nebo všech funkcí systému vlastností WPF vám ale pomůže využít tyto funkce.

Účelem vlastností závislosti je poskytnout způsob, jak vypočítat hodnotu vlastnosti na základě hodnoty jiných vstupů, například:

  • Systémové vlastnosti, jako jsou motivy a předvolby uživatele.
  • Mechanismy určování vlastností právě včas, jako jsou datové vazby a animace/scénáře.
  • Šablony s více použitími, jako jsou prostředky a styly.
  • Hodnoty známé prostřednictvím vztahů nadřazenosti a podřízenosti s jinými prvky ve stromu elementů.

Vlastnost závislosti může také poskytovat:

  • Samostatné ověřování.
  • Výchozí hodnoty.
  • Zpětná volání, která monitorují změny jiných vlastností.
  • Systém, který může vynutit hodnoty vlastností na základě informací z běhového prostředí.

Odvozené třídy mohou změnit některé vlastnosti existující vlastnosti přepsáním metadat vlastnosti závislosti, nikoli přepsáním skutečné implementace existujících vlastností nebo vytvořením nových vlastností.

V referenční dokumentaci SDK můžete identifikovat závislou vlastnost podle přítomnosti oddílu Informace o vlastnosti závislosti na spravované referenční stránce pro danou vlastnost. Část Informace o vlastnosti závislosti obsahuje odkaz na DependencyProperty pole identifikátoru pro danou vlastnost závislosti. Obsahuje také seznam možností metadat pro danou vlastnost ve třídě, informace o přepisech u jednotlivých tříd a další podrobnosti.

Vlastnosti závislostí podporují vlastnosti CLR

Vlastnosti závislostí a systém vlastností WPF rozšiřují funkce vlastností tím, že poskytují typ, který vrací vlastnost, jako alternativu ke standardnímu vzoru zálohování vlastnosti s privátním polem. Název tohoto typu je DependencyProperty. Dalším důležitým typem, který definuje systém vlastností WPF je DependencyObject, který definuje základní třídu, která může zaregistrovat a vlastnit vlastnost závislosti.

Tady je několik běžně používaných terminologie:

  • Vlastnost závislosti, což je vlastnost, která je podporována objektem DependencyProperty.

  • Identifikátor vlastnosti závislosti, což je instance získaná DependencyProperty jako návratová hodnota při registraci vlastnosti závislosti a poté uložena jako statický člen třídy. Mnoho rozhraní API, která pracují se systémem vlastností WPF, jako parametr používá identifikátor vlastnosti závislosti.

  • CLR "wrapper", který představuje implementace get a set pro vlastnost. Tyto implementace zahrnují identifikátor vlastnosti závislosti, který je použit v GetValue a SetValue voláních. Takto poskytuje systém vlastností WPF základ pro vlastnost.

Následující příklad definuje IsSpinning vlastnost závislosti, která zobrazí vztah DependencyProperty identifikátoru k vlastnosti, kterou vrací.

public static readonly DependencyProperty IsSpinningProperty = DependencyProperty.Register(
    "IsSpinning", typeof(bool),
    typeof(MainWindow)
    );

public bool IsSpinning
{
    get => (bool)GetValue(IsSpinningProperty);
    set => SetValue(IsSpinningProperty, value);
}
Public Shared ReadOnly IsSpinningProperty As DependencyProperty =
    DependencyProperty.Register("IsSpinning", GetType(Boolean), GetType(MainWindow))

Public Property IsSpinning As Boolean
    Get
        Return GetValue(IsSpinningProperty)
    End Get
    Set(value As Boolean)
        SetValue(IsSpinningProperty, value)
    End Set
End Property

Konvence pojmenování vlastnosti a jejího podpůrného pole DependencyProperty je důležitá. Název pole je vždy název vlastnosti s příponou Property připojena. Další informace o této konvenci a důvodech této konvence najdete v tématu Vlastní vlastnosti závislostí.

Nastavení hodnot vlastností

Vlastnosti můžete nastavit buď v kódu, nebo v XAML.

Nastavení hodnot vlastností v XAML

Následující příklad XAML nastaví barvu pozadí tlačítka na červenou. Řetězcová hodnota atributu XAML je převedena analyzátorem WPF XAML na typ WPF. Ve vygenerovaném kódu je typ WPF Color pomocí SolidColorBrush.

<Button Content="I am red" Background="Red"/>

XAML podporuje několik formulářů syntaxe pro nastavení vlastností. Která syntaxe, která se má použít pro konkrétní vlastnost, závisí na typu hodnoty, který vlastnost používá, a dalších faktorech, jako je přítomnost převaděče typů. Další informace o syntaxi XAML pro nastavení vlastností najdete v tématu XAML v WPF a syntaxi XAML Podrobně.

Následující příklad XAML ukazuje další pozadí tlačítka, které místo syntaxe atributu používá syntaxi prvku vlastnosti. Místo nastavení jednoduchého jednobarevného pozadí nastaví XAML vlastnost tlačítka Background na obrázek. Prvek představuje tento obrázek a atribut vnořeného elementu určuje zdroj image.

<Button Content="I have an image background">
    <Button.Background>
        <ImageBrush ImageSource="stripes.jpg"/>
    </Button.Background>
</Button>

Nastavení vlastností v kódu

Nastavení hodnot vlastností závislostí v kódu je obvykle jen volání set implementace poskytnuté "CLR 'wrapper'".

Button myButton = new();
myButton.Width = 200.0;
Dim myButton As New Button With {
    .Width = 200.0
}

Získání hodnoty vlastnosti je v podstatě voláním implementace „wrapper“ get.

double whatWidth = myButton.Width;
Dim whatWidth As Double = myButton.Width

Rozhraní API systému vlastností můžete také přímo volat GetValue a SetValue. Přímé volání rozhraní API je vhodné pro některé scénáře, ale obvykle ne v případě, že používáte existující vlastnosti. Obaly jsou obvykle pohodlnější a poskytují pro vývojářské nástroje lepší přístupnost vlastnosti.

Vlastnosti lze nastavit v XAML a pak k nim později přistupovat v kódu na pozadí. Podrobnosti najdete v tématu Kód a XAML ve WPF.

Funkce vlastností poskytovaná vlastností závislosti

Na rozdíl od vlastnosti, která je podporována polem, vlastnost závislosti rozšiřuje funkce vlastnosti. Přidané funkce často představují nebo podporují některou z těchto funkcí:

Prostředky

Hodnotu vlastnosti závislosti můžete nastavit odkazem na prostředek. Prostředky se obvykle zadávají jako hodnota vlastnosti Resources kořenového prvku stránky nebo aplikace, protože tato umístění nabízejí pohodlný přístup k prostředkům. V tomto příkladu definujeme zdroj SolidColorBrush:

<StackPanel.Resources>
    <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
</StackPanel.Resources>

Teď, když je prostředek definovaný, můžeme na prostředek odkazovat a poskytnout hodnotu vlastnosti Background :

<Button Background="{DynamicResource MyBrush}" Content="I am gold" />

V jazyce WPF XAML můžete použít statický nebo dynamický odkaz na prostředky. Na tento konkrétní prostředek se odkazuje jako na DynamicResource.

Poznámka:

Prostředky se považují za místní hodnotu, což znamená, že pokud nastavíte jinou místní hodnotu, odstraníte odkaz na prostředky. Další informace naleznete v tématu Priorita hodnoty vlastnosti závislosti.

Datová vazba

Vlastnost závislosti může odkazovat na hodnotu prostřednictvím datové vazby. Datová vazba funguje prostřednictvím konkrétní syntaxe rozšíření značek v jazyce XAML nebo objektu Binding v kódu. U datové vazby je stanovení konečné hodnoty vlastnosti odloženo do doby běhu, kdy se hodnota získá ze zdroje dat.

Následující příklad nastaví vlastnost Content pro Button pomocí vazby deklarované v XAML. Vazba využívá zděděný kontext dat a zdroj dat XmlDataProvider (není zobrazen). Samotná vazba určuje zdrojovou vlastnost v rámci zdroje dat pomocí XPath.

<Button Content="{Binding Source={StaticResource TestData}, XPath=test[1]/@text}"/>

Poznámka:

Vazby se považují za místní hodnotu, což znamená, že pokud nastavíte jinou místní hodnotu, odstraníte vazbu. Podrobnosti naleznete v tématu Priorita hodnoty vlastnosti závislostí.

Závislé vlastnosti ani třída DependencyObject nativně nepodporují INotifyPropertyChanged upozornění na změny ve zdrojové hodnotě vlastnosti DependencyObject pro operace datové vazby. Další informace o tom, jak vytvořit vlastnosti pro použití v datové vazbě, které můžou hlásit změny cíle datové vazby, najdete v tématu Přehled datových vazeb.

Styly

Styly a šablony jsou přesvědčivé důvody použití vlastností závislostí. Styly jsou zvláště užitečné pro nastavení vlastností, které definují uživatelské rozhraní aplikace. Styly jsou obvykle definovány jako prostředky v XAML. Styly interagují se systémem vlastností, protože obvykle obsahují nastavovací prvky pro konkrétní vlastnosti a spouštěče, které mění hodnotu vlastnosti na základě výpočetního času pro jinou vlastnost.

Následující příklad vytvoří jednoduchý styl, který by byl definován uvnitř slovníku Resources (není zobrazeno). Tento styl se pak použije přímo na Style vlastnost objektu Button. Funkce setter v rámci stylování nastaví vlastnost Background pro nastylovanou Button na zelenou.

<Style x:Key="GreenButtonStyle">
    <Setter Property="Control.Background" Value="Green"/>
</Style>
<Button Style="{StaticResource GreenButtonStyle}" Content="I am green"/>

Další informace najdete v tématu Styling a šablonování.

Animace

Vlastnosti závislostí můžou být animované. Při spuštění použité animace má animovaná hodnota vyšší prioritu než jakákoli jiná hodnota vlastnosti, včetně místní hodnoty.

Následující příklad animuje vlastnost Background v Button. Technicky vzato syntaxe elementu vlastnosti nastaví prázdný SolidColorBrush jako Background, a vlastnost Color objektu SolidColorBrush je animovaná.

<Button Content="I am animated">
    <Button.Background>
        <SolidColorBrush x:Name="AnimBrush"/>
    </Button.Background>
    <Button.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <ColorAnimation
                        Storyboard.TargetName="AnimBrush" 
                        Storyboard.TargetProperty="(SolidColorBrush.Color)"
                        From="Blue" To="White" Duration="0:0:1" 
                        AutoReverse="True" RepeatBehavior="Forever" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

Další informace o animaci vlastností najdete v tématu Přehled animací a Přehled storyboardů.

Nadřazení metadat

Při odvození z třídy, která původně zaregistrovala vlastnost závislosti, můžete změnit konkrétní chování vlastnosti závislosti přepsáním jeho metadat. Přepsání metadat spoléhá na DependencyProperty identifikátor a nevyžaduje reimplementování vlastnosti. Změna metadat je nativně zpracována systémem vlastností. Každá třída může obsahovat jednotlivá metadata pro všechny vlastnosti zděděné ze základních tříd na základě jednotlivých typů.

Následující příklad přepíše metadata pro DefaultStyleKey vlastnost závislosti. Přepsání metadat pro tuto konkrétní vlastnost závislosti je součástí implementačního vzoru pro vytváření ovládacích prvků, které mohou používat výchozí styly z motivů.

public class SpinnerControl : ItemsControl
{
    static SpinnerControl() => DefaultStyleKeyProperty.OverrideMetadata(
            typeof(SpinnerControl),
            new FrameworkPropertyMetadata(typeof(SpinnerControl))
        );
}
Public Class SpinnerControl
    Inherits ItemsControl
    Shared Sub New()
        DefaultStyleKeyProperty.OverrideMetadata(GetType(SpinnerControl), New FrameworkPropertyMetadata(GetType(SpinnerControl)))
    End Sub
End Class

Další informace o přepsání nebo přístupu k metadatům pro vlastnosti závislosti naleznete v tématu Přepsání metadat pro vlastnost závislosti.

Dědičnost hodnot vlastností

Prvek může dědit hodnotu vlastnosti závislosti ze svého nadřazeného prvku v objektovém stromě.

Poznámka:

Chování dědičnosti hodnot vlastností není globálně umožněno pro všechny vlastnosti závislosti, protože čas potřebný k výpočtu dědičnosti ovlivňuje výkon. Dědičnost hodnot vlastností je obvykle povolená pouze ve scénářích, které navrhují použitelnost. Pokud chcete zkontrolovat, zda je vlastnost závislosti děděna, podívejte se do části Informace o vlastnosti závislosti ve zdrojové dokumentaci SDK pro tuto vlastnost.

Následující příklad ukazuje vazbu, která zahrnuje DataContext vlastnost určující zdroj vazby. Vazby v podřízených objektech tedy nemusí určovat zdroj a mohou použít zděděnou hodnotu z DataContext nadřazeného StackPanel objektu. Nebo podřízený objekt může přímo zadat vlastní DataContext nebo Source v objektu Binding, a nikoli použít zděděnou hodnotu.

<StackPanel Canvas.Top="50" DataContext="{Binding Source={StaticResource TestData}}">
    <Button Content="{Binding XPath=test[2]/@text}"/>
</StackPanel>

Další informace naleznete v tématu Dědičnost hodnoty vlastnosti.

Integrace návrháře WPF

Vlastní ovládací prvky s vlastnostmi implementovanými jako vlastnosti závislostí se dobře integrují s návrhářem WPF pro Visual Studio. Jedním z příkladů je možnost upravit přímé a připojené vlastnosti závislostí v okně Vlastnosti . Další informace najdete v tématu Přehled vytváření ovládacích prvků.

Priorita hodnoty vlastnosti závislosti

Libovolný vstup založený na vlastnostech v rámci systému vlastností WPF může nastavit hodnotu vlastnosti závislosti. Priorita hodnot vlastnosti závislosti existuje proto, aby interakce různých scénářů, ve kterých vlastnosti získávají své hodnoty, byla předvídatelná.

Poznámka:

Dokumentace k sadě SDK někdy používá termín "místní hodnota" nebo "místně nastavená hodnota" při diskusi o vlastnostech závislosti. Místně nastavená hodnota je hodnota vlastnosti, která je nastavená přímo na instanci objektu v kódu nebo jako atribut elementu v XAML.

Další příklad obsahuje styl, který se vztahuje na Background vlastnost libovolného tlačítka, ale určuje jedno tlačítko s místně nastavenou Background vlastností. Technicky vzato má toto tlačítko Background nastavenou vlastnost dvakrát, i když platí pouze jedna hodnota – hodnota s nejvyšší prioritou. Místně nastavená hodnota má nejvyšší prioritu s výjimkou spuštěné animace, která tady neexistuje. Druhé tlačítko tedy používá hodnotu místně nastavené pro Background vlastnost místo hodnoty setter stylu. První tlačítko nemá žádnou místní hodnotu nebo jinou hodnotu s vyšší prioritou než setter stylu, a proto používá hodnotu setter stylu pro Background vlastnost.

<StackPanel>
    <StackPanel.Resources>
        <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
            <Setter Property="Background" Value="Orange"/>
        </Style>
    </StackPanel.Resources>
    <Button>I am styled orange</Button>
    <Button Background="Pink">I am locally set to pink (not styled orange)</Button>
</StackPanel>

Proč existuje priorita vlastností závislostí?

Místně nastavené hodnoty mají přednost před hodnotami setter stylu, které podporují místní řízení vlastností elementu. Podrobnosti naleznete v tématu Priorita hodnoty vlastnosti závislostí.

Poznámka:

Řada vlastností definovaných u elementů WPF nejsou vlastnosti závislosti, protože vlastnosti závislostí byly obvykle implementovány pouze v případě, že byla požadována funkce systému vlastností WPF. Mezi funkce patří datová vazba, styling, animace, podpora výchozí hodnoty, dědičnost, připojené vlastnosti a zneplatnění.

Další informace o vlastnostech závislostí

  • Vývojáři komponent nebo vývojáři aplikací mohou chtít vytvořit vlastní vlastnost závislosti pro přidání funkcí, jako jsou podpora datových vazeb nebo stylů, nebo zneplatnění a podpora převodu hodnot. Další informace naleznete v tématu vlastní vlastnosti závislostí.

  • Zvažte vlastnosti závislosti jako veřejné vlastnosti, přístupné nebo zjistitelné každým volajícím s přístupem k instanci. Další informace naleznete v tématu zabezpečení vlastností závislostí.

  • Připojená vlastnost je typ vlastnosti, která podporuje specializovanou syntaxi v XAML. Připojená vlastnost často neobsahuje shodu 1:1 s vlastností modulu CLR (Common Language Runtime) a nemusí nutně být vlastností závislosti. Hlavním účelem připojené vlastnosti je umožnit podřízeným prvkům hlásit hodnoty vlastností nadřazeného elementu, i když nadřazený element a podřízený prvek nezahrnují tuto vlastnost jako součást výpisů členů třídy. Jedním z hlavních scénářů je povolení podřízeného elementu informovat nadřazené prvky, jak je prezentovat v uživatelském rozhraní. Příklady, viz Dock a Left. Další informace naleznete v tématu Přehled připojených vlastností.

Viz také