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 obvykle 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. To zahrnuje použití existujících vlastností 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ě.

Předpoklady

Toto téma předpokládá, že máte základní znalosti o systému typů .NET a objektově orientovaném programování. Abyste mohli postupovat podle příkladů v tomto tématu, měli byste také pochopit XAML a vědět, jak psát aplikace WPF. Další informace naleznete v tématu Návod: Moje první desktopová aplikace WPF.

Vlastnosti závislostí a vlastnosti CLR

Ve WPF jsou vlastnosti obvykle vystaveny jako standardní vlastnosti .NET. Na základní úrovni můžete s těmito vlastnostmi pracovat přímo a nikdy nevíte, že jsou implementovány jako vlastnost závislosti. Měli byste se ale seznámit s některými nebo všemi funkcemi systému vlastností WPF, abyste mohli tyto funkce využít.

Účelem vlastností závislostí je poskytnout způsob, jak vypočítat hodnotu vlastnosti na základě hodnoty jiných vstupů. Mezi tyto další vstupy můžou patřit systémové vlastnosti, jako jsou motivy a předvolby uživatele, mechanismy určování vlastností za běhu, jako jsou vazby dat a animace/ scénáře, šablony s více použitím, jako jsou prostředky a styly, nebo hodnoty známé prostřednictvím vztahů nadřazených a podřízených prvků s jinými prvky ve stromu elementů. Kromě toho lze vlastnost závislosti implementovat tak, aby poskytovala samostatné ověřování, výchozí hodnoty, zpětné volání, které monitorují změny jiných vlastností, a systém, který může měnit hodnoty vlastností na základě potenciálně informací modulu runtime. Odvozené třídy mohou také změnit některé specifické vlastnosti existující vlastnosti přepsáním metadat vlastností závislostí, nikoli přepsáním skutečné implementace existujících vlastností nebo vytvořením nových vlastností.

V referenčních informacích sady SDK můžete určit, která vlastnost je vlastností závislosti, pomocí části Informace o vlastnosti závislosti na stránce spravovaného odkazu pro danou vlastnost. Část Informace o vlastnosti závislosti obsahuje odkaz na DependencyProperty pole identifikátoru pro danou vlastnost závislostí a obsahuje také seznam možností metadat, které jsou nastaveny pro danou vlastnost, informace o přepsání jednotlivých tříd a další podrobnosti.

Vlastnosti závislostí zpět – 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 k 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. DependencyObject definuje základní třídu, která může zaregistrovat a vlastnit vlastnost závislosti.

Následující seznam uvádí terminologii, která se používá s vlastnostmi závislostí:

  • Vlastnost závislosti: Vlastnost, která je podporována objektem DependencyProperty.

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

  • CLR "wrapper": Skutečný get a nastavit implementace pro vlastnost. Tyto implementace zahrnují identifikátor vlastnosti závislosti jeho použití v GetValue a SetValue volání, čímž poskytuje pozadí vlastnosti pomocí WPF systému vlastností.

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

public static readonly DependencyProperty IsSpinningProperty =
    DependencyProperty.Register(
    "IsSpinning", typeof(Boolean),
    typeof(MyCode)
    );
public bool IsSpinning
{
    get { return (bool)GetValue(IsSpinningProperty); }
    set { SetValue(IsSpinningProperty, value); }
}
Public Shared ReadOnly IsSpinningProperty As DependencyProperty =
    DependencyProperty.Register("IsSpinning",
                                GetType(Boolean),
                                GetType(MyCode))

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

Zásady vytváření názvů vlastnosti a jeho backingového DependencyProperty pole jsou důležité. Název pole je vždy název vlastnosti s připojenou příponou Property . Další informace o této konvenci a důvodech této konvence najdete v tématu Vlastní vlastnosti závislosti.

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 určuje barvu pozadí tlačítka červeně. Tento příklad znázorňuje případ, kdy je jednoduchá řetězcová hodnota atributu XAML převedena analyzátorem WPF XAML na typ WPF (a Color) SolidColorBrushve vygenerovaném kódu.

<Button Background="Red" Content="Button!"/>

XAML podporuje různé syntaxe formulářů pro nastavení vlastností. Která syntaxe, která se má použít pro konkrétní vlastnost, bude záviset na typu hodnoty, který vlastnost používá, a také na dalších faktorech, jako je přítomnost převaděče typů. Další informace o syntaxi XAML pro nastavení vlastností naleznete v xaml wpf a XAML syntaxe podrobně.

Jako příklad syntaxe bez atributu ukazuje následující příklad XAML další pozadí tlačítka. Tentokrát je místo nastavení jednoduché plné barvy pozadí nastaveno na obrázek s prvkem představujícím tento obrázek a zdroj obrázku určeným jako atribut vnořeného prvku. Toto je příklad syntaxe elementu vlastnosti.

<Button Content="Button!">
  <Button.Background>
    <ImageBrush ImageSource="wavy.jpg"/>
  </Button.Background>
</Button>

Nastavení vlastností v kódu

Nastavení hodnot vlastností závislostí v kódu je obvykle voláním implementace sady vystavené "obálkou" CLR.

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

Získání hodnoty vlastnosti je také v podstatě volání get "wrapper" implementace:

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

Můžete také volat rozhraní API GetValue systému vlastností a SetValue přímo. To obvykle není nutné, pokud používáte existující vlastnosti (obálky jsou pohodlnější a poskytují lepší expozici vlastnosti pro vývojářské nástroje), ale volání rozhraní API přímo je vhodné pro určité scénáře.

Vlastnosti lze také nastavit v XAML a pak k němu později v kódu přistupovat prostřednictvím kódu. Podrobnosti najdete v tématu Kód za kódem a XAML ve WPF.

Funkce vlastností poskytovaná vlastností závislosti

Vlastnost závislosti poskytuje funkce, které rozšiřují funkce vlastnosti na rozdíl od vlastnosti, která je podporována polem. Tyto funkce často představují nebo podporují jednu z následujících specifických funkcí:

Zdroje informací

Hodnotu vlastnosti závislosti lze nastavit odkazem na prostředek. Prostředky se obvykle zadají jako Resources hodnota vlastnosti kořenového prvku stránky nebo aplikace (tato umístění umožňují nejpohodlnější přístup k prostředku). Následující příklad ukazuje, jak definovat SolidColorBrush prostředek.

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

Jakmile je prostředek definovaný, můžete na něj odkazovat a použít ho k zadání hodnoty vlastnosti:

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

Na tento konkrétní prostředek se odkazuje jako na rozšíření značek DynamicResource (v JAZYCE WPF XAML můžete použít statický nebo dynamický odkaz na prostředky). Chcete-li použít dynamický odkaz na prostředky, musíte být nastaveni na vlastnost závislosti, takže se jedná konkrétně o použití dynamického odkazu na prostředky, které je povoleno systémem vlastností WPF. Další informace najdete v tématu Prostředky XAML.

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í Content vlastnost pro , Buttonpomocí vazby deklarované v XAML. Vazba používá zděděný kontext dat a XmlDataProvider zdroj dat (není zobrazený). Samotná vazba určuje požadovanou zdroj vlastnost v XPath rámci zdroje dat.

<Button Content="{Binding XPath=Team/@TeamName}"/>

Poznámka:

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

Vlastnosti závislostí nebo DependencyObject třída nativně nepodporují INotifyPropertyChanged pro účely vytváření oznámení o změnách ve DependencyObject zdrojové hodnotě vlastnosti pro operace vazby dat. 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 dvěma hlavními motivačními scénáři 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 komunikují se systémem vlastností, protože obvykle obsahují "setters" pro konkrétní vlastnosti a také triggery, které mění hodnotu vlastnosti na základě hodnoty v reálném čase pro jinou vlastnost.

Následující příklad vytvoří jednoduchý styl (který by byl definován uvnitř slovníku Resources , není zobrazen), pak tento styl použije přímo na Style vlastnost pro Button. Setter v rámci stylu nastaví Background vlastnost stylově Button na zelenou.

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

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

Animace

Vlastnosti závislostí můžou být animované. Když se použije animace a je spuštěná, animace funguje s vyšší prioritou než jakákoli hodnota (například místní hodnota), kterou má vlastnost jinak.

Následující příklad animuje Background na Button vlastnosti (technicky Background je animovaný pomocí syntaxe prvku vlastnosti k určení prázdné SolidColorBrush jako Background, pak Color vlastnost je to vlastnost, která SolidColorBrush je přímo animovaný).

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

Další informace o animaci vlastností naleznete v tématu Přehled animace a Přehled scénářů.

Přepsání metadat

Určité chování vlastnosti závislosti můžete změnit přepsáním metadat pro tuto vlastnost při odvození z třídy, která původně registruje vlastnost závislosti. Přepsání metadat závisí na identifikátoru DependencyProperty . Přepsání metadat nevyžaduje opětovné sestavení vlastnosti. Změna metadat je nativně zpracována systémem vlastností; každá třída může obsahovat jednotlivá metadata pro všechny vlastnosti, které jsou 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 vlastnost DefaultStyleKeyzávislosti . Přepsání tohoto konkrétního metadata vlastnosti závislosti je součástí vzoru implementace, který vytváří ovládací prvky, 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 získání metadat vlastností naleznete v tématu Metadata vlastností závislostí.

Dědičnost hodnoty vlastnosti

Prvek může dědit hodnotu vlastnosti závislosti z nadřazeného objektového stromu.

Poznámka:

Chování dědičnosti hodnot vlastností není globálně povolené pro všechny vlastnosti závislosti, protože doba výpočtu dědičnosti má určitý dopad na výkon. Dědičnost hodnot vlastností je obvykle povolena pouze pro vlastnosti, kde konkrétní scénář naznačuje, že dědičnost hodnot vlastností je vhodná. Pokud chcete zjistit, jestli se vlastnost závislostí dědí, podívejte se do části Informace o vlastnosti závislosti pro tuto vlastnost v odkazu na sadu SDK.

Následující příklad ukazuje vazbu a nastaví DataContext vlastnost, která určuje zdroj vazby, který nebyl zobrazen v předchozím příkladu vazby. Jakékoli následné vazby v podřízených objektech nemusí určovat zdroj, mohou použít zděděnou hodnotu z DataContext nadřazeného StackPanel objektu. (Případně by se podřízený objekt mohl místo toho rozhodnout, aby přímo určil vlastní DataContext nebo v objektu BindingSource a záměrně nepoužít zděděnou hodnotu pro kontext dat svých vazeb.)

<StackPanel Canvas.Top="50" DataContext="{Binding Source={StaticResource XmlTeamsSource}}">
  <Button Content="{Binding XPath=Team/@TeamName}"/>
</StackPanel>

Další informace naleznete v tématu Dědičnost hodnot vlastností.

Integrace návrháře WPF

Vlastní ovládací prvek s vlastnostmi implementovanými jako vlastnosti závislostí obdrží odpovídající podporu WPF Designeru pro Visual Studio. Jedním z příkladů je možnost upravit přímé a připojené vlastnosti závislostí pomocí okna Vlastnosti . Další informace najdete v tématu Přehled vytváření ovládacích prvků.

Priorita hodnot vlastností závislostí

Když získáte hodnotu vlastnosti závislosti, můžete získat hodnotu, která byla nastavena na této vlastnosti prostřednictvím některého z dalších vstupů založených na vlastnostech, které se účastní systému vlastností WPF. Priorita hodnoty vlastnosti závislosti existuje tak, aby různé scénáře, jak vlastnosti získávají své hodnoty předvídatelným způsobem.

Představte si následující příklad. Příklad obsahuje styl, který platí pro všechna tlačítka a jejich Background vlastnosti, ale pak také určuje jedno tlačítko s místně nastavenou Background hodnotou.

Poznámka:

V dokumentaci k sadě SDK se při diskusi o vlastnostech závislostí občas používají termíny "místní hodnota" nebo "místně nastavená hodnota". Místně nastavená hodnota je hodnota vlastnosti, která je nastavena přímo na instanci objektu v kódu nebo jako atribut prvku v XAML.

V zásadě platí, že pro první tlačítko je vlastnost nastavena dvakrát, ale pouze jedna hodnota platí: hodnota s nejvyšší prioritou. Místně nastavená hodnota má nejvyšší prioritu (s výjimkou spuštěné animace, ale v tomto příkladu se nepoužije žádná animace), a proto se místo hodnoty setter stylu na pozadí na prvním tlačítku použije místně nastavená hodnota. Druhé tlačítko nemá žádnou místní hodnotu (a žádnou jinou hodnotu s vyšší prioritou než setter stylu) a pozadí v daném tlačítku pochází ze setter stylu.

<StackPanel>
  <StackPanel.Resources>
    <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
     <Setter Property="Background" Value="Red"/>
    </Style>
  </StackPanel.Resources>
  <Button Background="Green">I am NOT red!</Button>
  <Button>I am styled red</Button>
</StackPanel>

Proč existuje priorita vlastností závislostí?

Obvykle byste nechtěli, aby styly vždy používaly a zakrývají dokonce i místně nastavenou hodnotu jednotlivého prvku (jinak by bylo obtížné použít styly nebo prvky obecně). Proto hodnoty, které pocházejí ze stylů, fungují s nižším předchůdcem než místně nastavená hodnota. Podrobnější výpis vlastností závislostí a umístění efektivní hodnoty vlastnosti závislosti může pocházet z tématu Priorita hodnoty vlastnosti závislosti.

Poznámka:

Existuje několik vlastností definovaných u elementů WPF, které nejsou vlastnostmi závislosti. Ve velké míře byly vlastnosti implementovány jako vlastnosti závislostí pouze v případě, že bylo potřeba podporovat alespoň jeden ze scénářů povolených systémem vlastností: datová vazba, styling, animace, podpora výchozí hodnoty, dědičnost, připojené vlastnosti nebo zneplatnění.

Učení další informace o vlastnostech závislostí

  • Připojená vlastnost je typ vlastnosti, která podporuje specializovanou syntaxi v XAML. Připojená vlastnost často nemá korespondenční hodnotu 1:1 s vlastností CLR (Common Language Runtime) a nemusí nutně být vlastností závislosti. Typickým účelem připojené vlastnosti je umožnit podřízeným prvkům hlásit hodnoty vlastností nadřazeného prvku, i když nadřazený prvek a podřízený prvek nemají tuto vlastnost jako součást výpisů členů třídy. Jedním z hlavních scénářů je umožnit podřízeným prvkům informovat nadřazené prvky, jak mají být prezentovány v uživatelském rozhraní; příklad, viz Dock nebo Left. Podrobnosti najdete v tématu Přehled připojených vlastností.

  • Vývojáři komponent nebo vývojáři aplikací mohou chtít vytvořit vlastní vlastnost závislosti, aby bylo možné povolit funkce, jako jsou podpora datových vazeb nebo stylů, nebo pro podporu zneplatnění a převodu hodnot. Podrobnosti najdete v tématu Vlastní vlastnosti závislosti.

  • Zvažte vlastnosti závislosti, aby byly veřejné vlastnosti, přístupné nebo alespoň zjistitelné všemi volajícími, kteří mají přístup k instanci. Další informace naleznete v tématu Zabezpečení vlastností závislostí.

Viz také