Attached Properties Overview
An attached property is a concept defined by Extensible Application Markup Language (XAML). An attached property is intended to be used as a type of global property that is settable on any object. In Windows Presentation Foundation (WPF), attached properties are typically defined as a specialized form of dependency property that does not have the conventional property "wrapper".
Este tópico contém as seguintes seções.
- Prerequisites
- Why Use Attached Properties
- Attached Properties in XAML
- How Attached Properties Are Used by the Owning Type
- Attached Properties in Code
- Attached Property Metadata
- Custom Attached Properties
- Learning More About Attached Properties
- Tópicos relacionados
Prerequisites
This topic assumes that you understand dependency properties from the perspective of a consumer of existing dependency properties on Windows Presentation Foundation (WPF) classes, and have read the Visão geral sobre propriedades de dependência. To follow the examples in this topic, you should also understand Extensible Application Markup Language (XAML) and know how to write WPF applications.
Why Use Attached Properties
One purpose of an attached property is to allow different child elements to specify unique values for a property that is actually defined in a parent element. A specific application of this scenario is having child elements inform the parent element of how they are to be presented in the user interface (UI). One example is the DockPanel.Dock property. The DockPanel.Dock property is created as an attached property because it is designed to be set on elements that are contained within a DockPanel, rather than on DockPanel itself. The DockPanel class defines the static DependencyProperty field named DockProperty, and then provides the GetDock and SetDock methods as public accessors for the attached property.
Attached Properties in XAML
In XAML, you set attached properties by using the syntax AttachedPropertyProvider.PropertyName
The following is an example of how you can set DockPanel.Dock in XAML:
<DockPanel>
<CheckBox DockPanel.Dock="Top">Hello</CheckBox>
</DockPanel>
Note that the usage is somewhat similar to a static property; you always reference the type DockPanel that owns and registers the attached property, rather than referring to any instance specified by name.
Also, because an attached property in XAML is an attribute that you set in markup, only the set operation has any relevance. You cannot directly get a property in XAML, although there are some indirect mechanisms for comparing values, such as triggers in styles (for details, see Styling and Templating).
Attached Property Implementation in WPF
In Windows Presentation Foundation (WPF), most of the attached properties that exist on WPF types are implemented as dependency properties. Attached properties are a XAML concept, whereas dependency properties are a WPF concept. Because WPF attached properties are dependency properties, they support dependency property concepts such as property metadata, and default values from that property metadata.
How Attached Properties Are Used by the Owning Type
Although attached properties are settable on any object, that does not automatically mean that setting the property will produce a tangible result, or that the value will ever be used by another object. Em geral, propriedades anexadas servem para que os objetos provenientes de uma grande variedade de hierarquias de classe possíveis ou relacionamentos lógicos podem cada informações comuns de relatório para o tipo que define a propriedade anexada. The type that defines the attached property typically follows one of these models:
The type that defines the attached property is designed so that it can be the parent element of the elements that will set values for the attached property. O tipo itera seus objetos filho por meio de uma lógica interna contra alguns estrutura de árvore do objeto, obtém os valores e age sobre esses valores de alguma maneira.
The type that defines the attached property will be used as the child element for a variety of possible parent elements and content models.
The type that defines the attached property represents a service. Other types set values for the attached property. Then, when the element that set the property is evaluated in the context of the service, the attached property values are obtained through internal logic of the service class.
An Example of a Parent-Defined Attached Property
The most typical scenario where WPF defines an attached property is when a parent element supports a child element collection, and also implements a behavior where the specifics of the behavior are reported individually for each child element.
DockPanel defines the DockPanel.Dock attached property, and DockPanel has class-level code as part of its rendering logic (specifically, MeasureOverride and ArrangeOverride). A DockPanel instance will always check to see whether any of its immediate child elements have set a value for DockPanel.Dock. If so, those values become input for the rendering logic applied to that particular child element. Aninhado DockPanel instâncias cada tratam suas próprias coleções de elementos filho imediato, mas esse comportamento é específico da implementação como DockPanel processos DockPanel.Dock valores. It is theoretically possible to have attached properties that influence elements beyond the immediate parent. If the DockPanel.Dock attached property is set on an element that has no DockPanel parent element to act upon it, no error or exception is raised. This simply means that a global property value was set, but it has no current DockPanel parent that could consume the information.
Attached Properties in Code
Attached properties in WPF do not have the typical CLR "wrapper" methods for easy get/set access. This is because the attached property is not necessarily part of the CLR namespace for instances where the property is set. However, a XAML reader must be able to set those values when XAML is processed. To be an effective attached property, the owner type of the attached property must implement dedicated accessor methods in the form GetPropertyName and SetPropertyName. Esses métodos do acessador dedicada também são úteis para obter ou definir o anexado a propriedade no código. From a code perspective, an attached property is similar to a backing field that has method accessors instead of property accessors, and that backing field can exist on any object rather than needing to be specifically defined.
The following example shows how you can set an attached property in code. In this example, myCheckBox is an instance of the CheckBox class.
Dim myDockPanel As New DockPanel()
Dim myCheckBox As New CheckBox()
myCheckBox.Content = "Hello"
myDockPanel.Children.Add(myCheckBox)
DockPanel.SetDock(myCheckBox, Dock.Top)
DockPanel myDockPanel = new DockPanel();
CheckBox myCheckBox = new CheckBox();
myCheckBox.Content = "Hello";
myDockPanel.Children.Add(myCheckBox);
DockPanel.SetDock(myCheckBox, Dock.Top);
Similar to the XAML case, if myCheckBox had not already been added as a child element of myDockPanel by the third line of code, the fourth line of code would not raise an exception, but the property value would not interact with a DockPanel parent and thus would do nothing. Only a DockPanel.Dock value set on a child element combined with the presence of a DockPanel parent element will cause an effective behavior in the rendered application. (Nesse caso, você poderia definir a propriedade anexada, e anexar a árvore. Ou você poderia anexar à árvore e definir a propriedade anexada. Qualquer ordem de ação fornece o mesmo resultado).
Attached Property Metadata
When registering the property, FrameworkPropertyMetadata is set to specify characteristics of the property, such as whether the property affects rendering, measurement, and so on. Metadata for an attached property is generally no different than on a dependency property. If you specify a default value in an override to attached property metadata, that value becomes the default value of the implicit attached property on instances of the overriding class. Specifically, your default value is reported if some process queries for the value of an attached property through the Get method accessor for that property, specifying an instance of the class where you specified the metadata, and the value for that attached property was otherwise not set.
If you want to enable property value inheritance on a property, you should use attached properties rather than non-attached dependency properties. For details, see Herança de Valor de Propriedade.
Custom Attached Properties
When to Create an Attached Property
You might create an attached property when there is a reason to have a property setting mechanism available for classes other than the defining class. The most common scenario for this is layout. Examples of existing layout properties are DockPanel.Dock, Panel.ZIndex, and Canvas.Top. The scenario enabled here is that elements that exist as child elements to layout-controlling elements are able to express layout requirements to their layout parent elements individually, each setting a property value that the parent defined as an attached property.
Another scenario for using an attached property is when your class represents a service, and you want classes to be able to integrate the service more transparently.
Yet another scenario is to receive Visual Studio 2008 WPF Designer support, such as Properties window editing. For more information, see Visão geral sobre criação de controles.
As mentioned before, you should register as an attached property if you want to use property value inheritance.
How to Create an Attached Property
If your class is defining the attached property strictly for use on other types, then the class does not have to derive from DependencyObject. But you do need to derive from DependencyObject if you follow the overall WPF model of having your attached property also be a dependency property.
Define your attached property as a dependency property by declaring a public static readonly field of type DependencyProperty. You define this field by using the return value of the RegisterAttached method. The field name must match the attached property name, appended with the string Property, to follow the established WPF pattern of naming the identifying fields versus the properties that they represent. The attached property provider must also provide static GetPropertyName and SetPropertyName methods as accessors for the attached property; failing to do this will result in the property system being unable to use your attached property.
Observação
Se você omitir o acessador de get da propriedade anexada, ligação de dados, a propriedade não funcionará em ferramentas de design, como Visual Studio e Expression Blend.
The Get Accessor
The signature for the GetPropertyName accessor must be:
public static object GetPropertyName(object target)
The target object can be specified as a more specific type in your implementation. For example, the DockPanel.GetDock method types the parameter as UIElement, because the attached property is only intended to be set on UIElement instances.
The return value can be specified as a more specific type in your implementation. For example, the GetDock method types it as Dock, because the value can only be set to that enumeration.
The Set Accessor
The signature for the SetPropertyName accessor must be:
public static void SetPropertyName(object target, object value)
The target object can be specified as a more specific type in your implementation. For example, the SetDock method types it as UIElement, because the attached property is only intended to be set on UIElement instances.
The value object can be specified as a more specific type in your implementation. For example, the SetDock method types it as Dock, because the value can only be set to that enumeration. Remember that the value for this method is the input coming from the XAML loader when it encounters your attached property in an attached property usage in markup. That input is the value specified as a XAML attribute value in markup. Therefore there must be type conversion, value serializer, or markup extension support for the type you use, such that the appropriate type can be created from the attribute value (which is ultimately just a string).
The following example shows the dependency property registration (using the RegisterAttached method), as well as the GetPropertyName and SetPropertyName accessors. In the example, the attached property name is IsBubbleSource. Therefore, the accessors must be named GetIsBubbleSource and SetIsBubbleSource.
Public Shared ReadOnly IsBubbleSourceProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsBubbleSource", GetType(Boolean), GetType(AquariumObject), New FrameworkPropertyMetadata(False, FrameworkPropertyMetadataOptions.AffectsRender))
Public Shared Sub SetIsBubbleSource(ByVal element As UIElement, ByVal value As Boolean)
element.SetValue(IsBubbleSourceProperty, value)
End Sub
Public Shared Function GetIsBubbleSource(ByVal element As UIElement) As Boolean
Return CType(element.GetValue(IsBubbleSourceProperty), Boolean)
End Function
public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
"IsBubbleSource",
typeof(Boolean),
typeof(AquariumObject),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)
);
public static void SetIsBubbleSource(UIElement element, Boolean value)
{
element.SetValue(IsBubbleSourceProperty, value);
}
public static Boolean GetIsBubbleSource(UIElement element)
{
return (Boolean)element.GetValue(IsBubbleSourceProperty);
}
Attached Property Attributes
WPF defines several .NET Framework attributes that are intended to provide information about attached properties to reflection processes, and to typical users of reflection and property information such as designers. Because attached properties have a type of unlimited scope, designers need a way to avoid overwhelming users with a global list of all the attached properties that are defined in a particular technology implementation that uses XAML. The .NET Framework attributes that WPF defines for attached properties can be used to scope the situations where a given attached property should be shown in a properties window. You might consider applying these attributes for your own custom attached properties also. The purpose and syntax of the .NET Framework attributes is described on the appropriate reference pages:
Learning More About Attached Properties
For more information on creating an attached property, see Como: Register an Attached Property.
For more advanced usage scenarios for dependency properties and attached properties, see Propriedades de Dependência Personalizada.
You can also register a property as an attached property, and as a dependency property, but then still expose "wrapper" implementations. In this case, the property can be set either on that element, or on any element through the XAML attached property syntax. An example of a property with an appropriate scenario for both standard and attached usages is FrameworkElement.FlowDirection.
Consulte também
Tarefas
Como: Register an Attached Property
Referência
Conceitos
Visão geral sobre propriedades de dependência