Compartilhar via


Visão geral sobre propriedades de dependência

Windows Presentation Foundation (WPF)Fornece um conjunto de serviços que podem ser usados para estender a funcionalidade de um common language runtime (CLR) propriedade. Collectively, these services are typically referred to as the WPF property system. Uma propriedade que tem o respaldo da WPF o sistema de propriedade é conhecido como um propriedade de dependência. Esta visão geral descreve o WPF o sistema de propriedade e os recursos de um propriedade de dependência. Isso inclui como usar existente Propriedades de dependência no XAML e no código. This overview also introduces specialized aspects of dependency properties, such as dependency property metadata, and how to create your own dependency property in a custom class.

Este tópico contém as seguintes seções.

  • Prerequisites
  • Dependency Properties and CLR Properties
  • Dependency Properties Back CLR Properties
  • Setting Property Values
  • Property Functionality Provided by a Dependency Property
  • Dependency Property Value Precedence
  • Learning More About Dependency Properties
  • Tópicos relacionados

Prerequisites

This topic assumes that you have some basic knowledge of the CLR and object-oriented programming. In order to follow the examples in this topic, you should also understand XAML and know how to write WPF applications. For more information, see Demonstra Passo a passo: Guia de Introdução do WPF.

Dependency Properties and CLR Properties

In WPF, properties are typically exposed as common language runtime (CLR) properties. Em um nível básico, você pode interagir com essas propriedades diretamente e nunca se sabe que eles são implementados como um propriedade de dependência. No entanto, você deve se familiarizar com alguns ou todos os recursos da WPF o sistema de propriedades, para que você pode aproveitar esses recursos.

The purpose of dependency properties is to provide a way to compute the value of a property based on the value of other inputs. These other inputs might include system properties such as themes and user preference, just-in-time property determination mechanisms such as data binding and animations/storyboards, multiple-use templates such as resources and styles, or values known through parent-child relationships with other elements in the element tree. In addition, a dependency property can be implemented to provide self-contained validation, default values, callbacks that monitor changes to other properties, and a system that can coerce property values based on potentially runtime information. Derived classes can also change some specific characteristics of an existing property by overriding dependency property metadata, rather than overriding the actual implementation of existing properties or creating new properties.

In the SDK reference, you can identify which property is a dependency property by the presence of the Dependency Property Information section on the managed reference page for that property. The Dependency Property Information section includes a link to the DependencyProperty identifier field for that dependency property, and also includes a list of the metadata options that are set for that property, per-class override information, and other details.

Dependency Properties Back CLR Properties

Dependency properties and the WPF property system extend property functionality by providing a type that backs a property, as an alternative implementation to the standard pattern of backing the property with a private field. The name of this type is DependencyProperty. The other important type that defines the WPF property system is DependencyObjectDependencyObject defines the base class that can register and own a dependency property.

Following is a summation of the terminology that is used in this software development kit (SDK) documentation when discussing dependency properties:

  • Propriedade de dependência: Uma propriedade que é feita por um DependencyProperty.

  • Identificador de propriedade de dependência: A DependencyProperty instância, o que é obtida como um valor de retorno ao registrar um propriedade de dependênciae em seguida, é armazenado como um membro estático de uma classe. Esse identificador é usado como um parâmetro para muitos da APIs que interagem com o WPF sistema de propriedade.

  • CLR "empacotador": Obter e definir implementações da propriedade real. These implementations incorporate the dependency property identifier by using it in the GetValue and SetValue calls, thus providing the backing for the property using the WPF property system.

The following example defines the IsSpinning dependency property, and shows the relationship of the DependencyProperty identifier to the property that it backs.

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
public static readonly DependencyProperty IsSpinningProperty = 
    DependencyProperty.Register(
    "IsSpinning", typeof(Boolean),


...


    );
public bool IsSpinning
{
    get { return (bool)GetValue(IsSpinningProperty); }
    set { SetValue(IsSpinningProperty, value); }
}

The naming convention of the property and its backing DependencyProperty field is important. The name of the field is always the name of the property, with the suffix Property appended. For more information about this convention and the reasons for it, see Propriedades de Dependência Personalizada.

Setting Property Values

Você pode definir propriedades no código ou em XAML.

Setting Property Values in XAML

O exemplo a seguir XAML especifica a cor de plano de fundo de um botão vermelho. Este exemplo ilustra um caso onde o valor de cadeia de caracteres simples para um atributo XAML é o tipo convertido pelo analisador WPF XAML em um WPF tipo (uma Color, por meio de um SolidColorBrush) no código gerado.

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

XAML oferece suporte a uma variedade de formas de sintaxe para definir as propriedades. Which syntax to use for a particular property will depend on the value type that a property uses, as well as other factors such as the presence of a type converter. Para obter mais informações sobre a sintaxe XAML para definição da propriedade, consulte Visão geral do XAML (WPF) e Sintaxe XAML em detalhes.

Como um exemplo de sintaxe de não-atributo, o exemplo XAML a seguir mostra outro plano de fundo do botão. This time rather than setting a simple solid color, the background is set to an image, with an element representing that image and the source of that image specified as an attribute of the nested element. This is an example of property element syntax.

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

Setting Properties in Code

Setting dependency property values in code is typically just a call to the set implementation exposed by the CLR "wrapper". 

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

Getting a property value is also essentially a call to the get "wrapper" implementation:

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

You can also call the property system APIs GetValue and SetValue directly. This is not typically necessary if you are using existing properties (the wrappers are more convenient, and provide better exposure of the property for developer tools), but calling the APIs directly is appropriate for certain scenarios.

Propriedades podem ser também definidas em XAML e, em seguida, são acessadas posteriormente no código, por meio de code-behind. For details, see Code-Behind e XAML no WPF.

Property Functionality Provided by a Dependency Property

A dependency property provides functionality that extends the functionality of a property as opposed to a property that is backed by a field. Em geral, cada tal funcionalidade representa ou oferece suporte a um recurso específico do gerais WPF conjunto de recursos:

  • Resources

  • Data binding

  • Styles

  • Animations

  • Metadata overrides

  • Property value inheritance

  • WPF Designer integration

Resources

A dependency property value can be set by referencing a resource. Recursos geralmente são especificados como o Resources o valor da propriedade de um elemento raiz da página ou do aplicativo (o acesso mais conveniente para o recurso de enable nesses locais). The following example shows how to define a SolidColorBrush resource.

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

Once the resource is defined, you can reference the resource and use it to provide a property value:

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

Este recurso específico é referenciado como um Extensão de marcação DynamicResource (em WPF XAML, você pode usar uma referência de recurso estático ou dinâmico). To use a dynamic resource reference, you must be setting to a dependency property, so it is specifically the dynamic resource reference usage that is enabled by the WPF property system. For more information, see Visão geral sobre Recursos.

Observação

Resources are treated as a local value, which means that if you set another local value, you will eliminate the resource reference.For more information, see Precedência de valores de propriedade de dependência.

Data Binding

A dependency property can reference a value through data binding. Ligação de dados funciona através de uma sintaxe de extensão de marcação específica no XAML, ou o Binding o objeto no código. With data binding, the final property value determination is deferred until run time, at which time the value is obtained from a data source.

O exemplo a seguir define o Content propriedade para um Button, usando uma ligação declarada em XAML. The binding uses an inherited data context and an XmlDataProvider data source (not shown). The binding itself specifies the desired source property by XPath within the data source.

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

Observação

Bindings are treated as a local value, which means that if you set another local value, you will eliminate the binding.For details, see Precedência de valores de propriedade de dependência.

Dependency properties, or the DependencyObject class, do not natively support INotifyPropertyChanged for purposes of producing notifications of changes in DependencyObject source property value for data binding operations. For more information on how to create properties for use in data binding that can report changes to a data binding target, see Revisão de Associação de Dados.

Styles

Styles and templates are two of the chief motivating scenarios for using dependency properties. Styles are particularly useful for setting properties that define application user interface (UI). Estilos são normalmente definidos como recursos em XAML. Estilos de interagem com o sistema de propriedade porque eles geralmente contêm "setters" para determinadas propriedades, bem como "disparadores" que alterar um valor de propriedade com base no valor em tempo real para outra propriedade.

The following example creates a very simple style (which would be defined inside a Resources dictionary, not shown), then applies that style directly to the Style property for a Button. The setter within the style sets the Background property for a styled Button to green.

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

For more information, see Styling and Templating.

Animations

Dependency properties can be animated. When an animation is applied and is running, the animated value operates at a higher precedence than any value (such as a local value) that the property otherwise has.

The following example animates the Background on a Button property (technically, the Background is animated by using property element syntax to specify a blank SolidColorBrush as the Background, then the Color property of that SolidColorBrush is the property that is directly animated).

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

For more information on animating properties, see Revisão de Animação and Visão geral sobre Storyboards.

Metadata Overrides

You can change certain behaviors of a dependency property by overriding the metadata for that property when you derive from the class that originally registers the dependency property. Overriding metadata relies on the DependencyProperty identifier. Overriding metadata does not require re-implementing the property. The metadata change is handled natively by the property system; each class potentially holds individual metadata for all properties that are inherited from base classes, on a per-type basis.

O exemplo a seguir substitui os metadados para uma propriedade de dependência DefaultStyleKey. Overriding this particular dependency property metadata is part of an implementation pattern that creates controls that can use default styles from themes.

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

For more information about overriding or obtaining property metadata, see Metadados de Propriedade de Dependência.

Property Value Inheritance

Um elemento pode herdar o valor de uma propriedade de dependência de seu pai na árvore de objetos.

Observação

Property value inheritance behavior is not globally enabled for all dependency properties, because the calculation time for inheritance does have some performance impact.Property value inheritance is typically only enabled for properties where a particular scenario suggests that property value inheritance is appropriate.Você pode determinar se uma propriedade de dependência herda observando o Informações de propriedade de dependência seção para essa propriedade de dependência na referência do SDK.

The following example shows a binding, and sets the DataContext property that specifies the source of the binding, which was not shown in the earlier binding example. Qualquer ligações subseqüentes em objetos filho não precisam especificar a fonte, eles podem usar o valor herdado do DataContext no pai StackPanel objeto. (Como alternativa, um objeto filho poderia optar por especificar diretamente seu próprio DataContext ou um Source na Bindinge deliberadamente não usar o valor herdado para o contexto de dados de vinculações.)

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

For more information, see Herança de Valor de Propriedade.

WPF Designer Integration

Um controle personalizado com propriedades que são implementadas como propriedades de dependência receberá apropriado WPF Designer for Visual Studio suporte. Um exemplo é a capacidade de editar as propriedades de dependência direta e conectados com o Propriedades janela. For more information, see Visão geral sobre criação de controles.

Dependency Property Value Precedence

When you get the value of a dependency property, you are potentially obtaining a value that was set on that property through any one of the other property-based inputs that participate in the WPF property system. Dependency property value precedence exists so that a variety of scenarios for how properties obtain their values can interact in a predictable way.

Consider the following example. The example includes a style that applies to all buttons and their Background properties, but then also specifies one button with a locally set Background value.

Observação

The SDK documentation uses the terms "local value" or "locally set value" occasionally when discussing dependency properties.Definido localmente é um valor de propriedade é definido diretamente em uma instância do objeto no código ou como um atributo em um elemento no XAML.

Em princípio, para o primeiro botão, a propriedade é definida duas vezes, mas apenas um valor se aplica: o valor com maior precedência. A locally set value has the highest precedence (except for a running animation, but no animation applies in this example) and thus the locally set value is used instead of the style setter value for the background on the first button. The second button has no local value (and no other value with higher precedence than a style setter) and thus the background in that button comes from the style setter.

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

Why Does Dependency Property Precedence Exist?

Typically, you would not want styles to always apply and to obscure even a locally set value of an individual element (otherwise, it would be very difficult to use either styles or elements in general). Therefore, the values that come from styles operate at a lower precedent than a locally set value. For a more thorough listing of dependency properties and where a dependency property effective value might come from, see Precedência de valores de propriedade de dependência.

Observação

There are a number of properties defined on WPF elements that are not dependency properties.Em geral, propriedades foram implementadas como propriedades de dependência somente quando havia necessidades para oferecer suporte a pelo menos um dos cenários habilitados pelo sistema de propriedade: ligação de dados, estilos, animação, suporte de valor padrão, herança, propriedades anexadas ou invalidação.

Learning More About Dependency Properties

  • Um anexado a propriedade é um tipo de propriedade que oferece suporte a uma sintaxe especializada em XAML. An attached property often does not have a 1:1 correspondence with a common language runtime (CLR) property, and is not necessarily a dependency property. The typical purpose of a attached property is to allow child elements to report property values to a parent element, even if the parent element and child element do not both possess that property as part of the class members listings. One primary scenario is to enable child elements to inform the parent how they should be presented in UI; for an example, see Dock or Left. For details, see Attached Properties Overview.

  • Component developers or application developers may wish to create their own dependency property, in order to enable capabilities such as data binding or styles support, or for invalidation and value coercion support. For details, see Propriedades de Dependência Personalizada.

  • Dependency properties should generally be considered to be public properties, accessible or at least discoverable by any caller that has access to an instance. For more information, see Segurança de Propriedades de Dependência.

Consulte também

Conceitos

Propriedades de Dependência Personalizada

Read-Only Dependency Properties

Visão geral do XAML (WPF)

Arquitetura WPF