Přehled vlastností závislostí (WPF .NET)

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ě.

Důležité

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

Předpoklady

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í za běhu, 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:

  • Ověřování s vlastním obsahem.
  • Výchozí hodnoty.
  • Zpětná volání, která monitorují změny jiných vlastností.
  • Systém, který může vyřaovat hodnoty vlastností na základě informací o modulu runtime.

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 odkazu na sadu SDK můžete identifikovat vlastnost závislosti přítomností oddílu Informace o vlastnosti závislosti na stránce spravovaných referenčních informací 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, 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 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", což je get a set implementace vlastnosti. Tyto implementace zahrnují identifikátor vlastnosti závislosti jeho použitím v rámci GetValue volání a SetValue volání. Tímto způsobem poskytuje systém vlastností WPF pozadí vlastnosti.

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

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á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. Vygenerovaný kód je typ WPF , Colorprostřednictvím .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í naleznete v xaml wpf a XAML syntaxe Podrobně.

Následující příklad XAML ukazuje další tlačítko pozadí, které místo syntaxe atributu používá syntaxi elementu property. Místo nastavení jednoduché plné barvy 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 vystavené 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í get implementace "wrapper":

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

Můžete také volat rozhraní API GetValue systému vlastností a SetValue přímo. 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. Obálky jsou obvykle pohodlnější a poskytují lepší expozici vlastnosti pro vývojářské nástroje.

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 kódu 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í:

Zdroje informací

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

<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. Dynamické odkazy na prostředky lze použít pouze k nastavení vlastnosti závislosti, takže se jedná o konkrétně 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 zdroj vlastnost v rámci zdroje dat .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í.

Vlastnosti závislostí nebo DependencyObject třída nativně nepodporují INotifyPropertyChanged oznámení změn ve DependencyObject zdrojové hodnotě vlastnosti 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 pracují se systémem vlastností, protože obvykle obsahují "setters" pro konkrétní vlastnosti a "triggery", které mění hodnotu vlastnosti na základě hodnoty modulu runtime 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. 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}" 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 Background vlastnost Button. Technicky vzato syntaxe elementu vlastnosti nastaví prázdnou SolidColorBrush hodnotu jako Backgrounda Color vlastnost 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 scénářů.

Přepsání 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í vzoru implementace 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 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 ovlivňuje výkon. Dědičnost hodnot vlastností je obvykle povolená pouze ve scénářích, které navrhují použitelnost. Pokud chcete zkontrolovat, jestli 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, 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 hodnot vlastností.

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í obsahu ovládacích prvků.

Priorita hodnot vlastností závislostí

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

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í.

Učení 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, aby byly veřejné vlastnosti, přístupné nebo zjistitelné jakýmkoli 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é