[ACCEPTED]-How exactly do Attached Properties work in WPF?-attached-properties

Accepted answer
Score: 46

There are two concepts here: dependency properties and attached dependency properties. "Attached 32 Properties" are dependency properties, and 31 as such support dependency property value inheritance.

About basic 30 dependency properties, a very rough statement 29 would be that they basically inherit their 28 values from parent elements in the wpf (logical/visual) tree. A 27 dependency property (attached or not) inherits 26 its value "downwards" if its metadata is 25 set with the FrameworkPropertyMetadataOptions.Inherit flag, and in many cases this 24 is so.

Attached properties are properties 23 which can be set on any wpf object (basically, at least a 22 DependencyObject) via the DependencyObject.SetValue method. The purpose 21 for this mechanism is to "attach" to 20 other objects information needed by parent 19 objects, not the child objects themselves. For 18 example, the Grid.Row is an attached property required 17 by the Grid to place items within its render 16 area.

Dependency properties are inherited 15 "downwards" automatically by the 14 wpf object system.

Attached properties are 13 examined "upwards" explicitly, in 12 the code of specific objects. In the case 11 of Grid, upon determining where to place 10 its items, it checks for the value of Grid.Row 9 and Grid.Column attached properties on each 8 contained item.

It is also often the technique 7 to create custom attached properties which 6 modify in some way the objects they are 5 attached to (for example, the Drag'n'Drop functionality via attached properties).

As an additional 4 note, a good example of an inheriting attached 3 property is TextElement.FontFamily. Grid.Row and Grid.Column properties 2 do not have the Inherits flag set.

TextElement.FontFamily, from 1 Reflector:

FontFamilyProperty = DependencyProperty.RegisterAttached("FontFamily", typeof(FontFamily), typeof(TextElement), new FrameworkPropertyMetadata(SystemFonts.MessageFontFamily, FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(TextElement.IsValidFontFamily));

Grid.Row, from Reflector:

RowProperty = DependencyProperty.RegisterAttached("Row", typeof(int), typeof(Grid), new FrameworkPropertyMetadata(0, new PropertyChangedCallback(Grid.OnCellAttachedPropertyChanged)), new ValidateValueCallback(Grid.IsIntValueNotNegative));
Score: 2

From MSDN:

Although attached properties are settable 56 on any object, that does not automatically 55 mean that setting the property will produce 54 a tangible result, or that the value will 53 ever be used by another object. Generally, attached 52 properties are intended so that objects 51 coming from a wide variety of possible class 50 hierarchies or logical relationships can 49 each report common information to the type 48 that defines the attached property. The 47 type that defines the attached property 46 typically follows one of these models:

  • The 45 type that defines the attached property 44 is designed so that it can be the parent 43 element of the elements that will set values 42 for the attached property. The type then 41 iterates its child objects through internal 40 logic against some object tree structure, obtains 39 the values, and acts on those values in 38 some manner.

  • The type that defines the attached property 37 will be used as the child element for a 36 variety of possible parent elements and 35 content models.

  • The type that defines the 34 attached property represents a service. Other types 33 set values for the attached property. Then, when 32 the element that set the property is evaluated 31 in the context of the service, the attached property 30 values are obtained through internal logic 29 of the service class.

An Example of a Parent-Defined Attached Property

The most typical scenario 28 where WPF defines an attached property is 27 when a parent element supports a child element 26 collection, and also implements a behavior 25 where the specifics of the behavior are 24 reported individually for each child element.

DockPanel 23 defines the DockPanel.Dock attached property, and 22 DockPanel has class-level code as part of 21 its rendering logic (specifically, MeasureOverride 20 and ArrangeOverride). A DockPanel instance 19 will always check to see whether any of 18 its immediate child elements have set a 17 value for DockPanel.Dock. If so, those values 16 become input for the rendering logic applied 15 to that particular child element. Nested 14 DockPanel instances each treat their own 13 immediate child element collections, but 12 that behavior is implementation-specific 11 to how DockPanel processes DockPanel.Dock 10 values. It is theoretically possible to 9 have attached properties that influence 8 elements beyond the immediate parent. If 7 the DockPanel.Dock attached property is 6 set on an element that has no DockPanel 5 parent element to act upon it, no error 4 or exception is raised. This simply means 3 that a global property value was set, but 2 it has no current DockPanel parent that 1 could consume the information.

Score: 2

In simple words this is how I understand 12 it (please correct me if I'm wrong).

An object 11 (A) implements a property that will attach 10 to another object (B) (object B doesn't 9 even know about the existence of this "attachable" property). Object 8 B needs to inherit from DependencyObject.

Object 7 A also implements a static method to check 6 for it's "attachable" property in other 5 objects, A.GetAttachedProperty(B).

If B 4 has the attached property from A, A.GetAttachedProperty 3 will read and return it's value. Otherwise 2 A will try to read it, and return null since 1 it's not there.

More Related questions