Tuesday 8 June 2010

Attached vs regular dependency properties

With dependency properties the backing store of the property is an object of type DependencyProperty instead of what would normally be a private field. Dependency properties can come in 2 forms: attached or not attached.

Regular dependency properties are set on a DependencyObject just like any other .NET property.

Attached dependency properties are associated with a DependencyObject (e.g. Grid) but are set on a separate DependencyObject, often a child of the DependencyObject that defines the attached property (e.g. Grid.Row, an attached property, is set on the children of a parent Grid).

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…

…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). *

When manipulating dependency properties in code the DependencyProperty.Register() method is used to register a normal unattached dependency property on a DependencyObject. DependencyProperty.RegisterAttached() is used to set an attached dependency 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. * (my bold)

* http://msdn.microsoft.com/en-us/library/ms749011.aspx

See also http://stackoverflow.com/questions/910579/dependencyproperty-register-or-registerattached

Dependency property example

public string MyProperty 
{
    get { return (string)GetValue(MyPropertyProperty); }
    set { SetValue(MyPropertyProperty, value); } 
} 

public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register("MyProperty", typeof(string), typeof(MyClass), new PropertyMetadata(""));

The Register() static method accepts a class of type PropertyMetadata that, among other things, sets the default value of the property. Remember there is also a RegisterAttached() version for attached properties.

Differences between Silverlight and WPF

The differences between Silverlight and WPF reside in the metadata structure: Silverlight only supports the PropertyMetadata class here, while WPF supports several classes (all derived from PropertyMetadata).