Under the hood: Dependency Properties - Rudi Grobler

Under the hood: Dependency Properties

Dependency Properties are a huge part of what makes WPF work so I decided to spend a little time on the subject! As the name implies, Dependency Properties are properties that depend on other factors.  The value of a dependency property can be determined by a variety of factors, enabling features such as real-time property validation and notifying related properties of changes to value for other properties.

A little bit of history

To understand dependency properties, you have to remember the good old days of normal CLR properties. If you missed that part, here is a quick recap: Properties basically uses a getter and a setter to set a private variable.

private bool IsEmptyValue;
public bool IsEmpty
{
    get { 
return IsEmptyValue}
    set { IsEmptyValue 
value}
}

.NET Framework 3.0 added a quick way to define a property

public bool IsEmpty
{
    get
;
    
set;
}

Now for the good stuff...

There is now better way to start learning something new then by doing it. Charles Petzold's book Application = Markup + Code has an excellent example of how to test the basics of dependency properties. The application creates a Window and adds a grid to the content of this window. The grid is then divided into 2 rows and 3 columns. Each cell gets 1 button. The top row's buttons basically change the font size of the window and the bottom row changes the font size of the button. The important features to notice is that once a buttons font size has been changed, then changing the font size using the windows font size has no effect. This indicates that there is some order of precedence in setting the value of a property.

Order of precedence

  • 1. Property system coercion
  • 2. Active animation

•3.       Local value

  • 4. TemplateParent template
  • 5. Style triggers
  • 6. Template triggers
  • 7. Style setters
  • 8. Theme style

•9.       Inheritance

•10.   Default value

From this list we can deduct why the application functions the way it does. Once the button is created, it gets it default value from its metadata. This is the lowest value it can have. If the font size of the window gets changed, then the buttons inherit this value. This inherited value is of slight higher precedence. If you manually set the value of a button, then inheritance is ignored because it has a lower precedence than manually setting the buttons value.

This is a very important concept to grasp. Another interesting thing to note is that the grid has no FontSize property but the FontSize property of the Window gets passed down to all children of this grid.

How to implement a Dependency Properties

A class can only define dependency properties if it is derived from DependencyObject. This provides all the basic functionality required to implement dependency properties. The 3 most important methods defined are SetValue, GetValue and ClearValue. Have a look at an older post I made about dependency properties to see how to implement them.

http://dotnet.org.za/rudi/archive/2007/05/21/dependency-properties.aspx

Why use Dependency Properties?

So, inheritance is great but what else can these properties do? Dependency properties have very well defined set of metadata that can be set per property. Some of the options that can be defined with this metadata is the default value, can it be inherited, etc. Dependency Properties facilitate attached properties. I will hopefully cover attached properties later, but for now just know that attached properties are often used in WPF to simplify layout. Dependency properties also provide self-contained validation handling and of course dependency properties are XAML friendly. This allows other features like data binding, styling, animation, etc...

Where is Dependency Properties used?

Well, the short answer is basically everywhere... Properly the biggest example of using dependency properties is FrameworkElement.DataContext. This property is inherited by all the decedents and can thus implicitly share the same data source. The example out of Charles Petzold's book used the FontSize property.

For more detailed information, have a look at the 3 articles Josh Smith wrote at http://joshsmithonwpf.wordpress.com/. The sample code from Charles Petzold's book can be downloaded from his homepage at http://www.charlespetzold.com/.

Disclaimer

The following article is based on my personal testing, code from Charles Petzolds book, great articles on Josh Smith's blog about Dependency Properties and also some research on MSDN

kick it on DotNetKicks.com
Published Monday, July 02, 2007 5:39 PM by rudi
Filed under: ,

Comments

# re: Under the hood: Dependency Properties

The ClearValue method provides an expedient means to clear any locally applied value from a dependency property that is set on an element. However, calling ClearValue is not guarantee that the default as established in metata during property registration is the new effective value. All other participants in value precedence are still active. Only the locally set value has been removed from the precedence sequence.

The following is taken from a MSDN article I found. Have a look at the following forum entry I made a while ago were I tried to figure out how the SetValue/ClearValue worked.

forums.microsoft.com/.../ShowPost.aspx

Just remember that ClearValue only clears the locally set value, so if you have a default value and it then inherits a new value and then gets a local value, the ClearValue wil then only remove the lcoal value and would revert back to the inherited value and NOT the metadata default. I initially did not understand this...

Wednesday, July 04, 2007 3:55 PM by rudi

# re: Under the hood: Dependency Properties

Some other properties defined as DependencyProperty:

UIElement -> AllowDrop, IsEnabled, IsVisible, SnapToDevicePrixels

FrameworkElement -> CultureInfo, FlowDirection, InputScope

Control -> FontFamily, FontSize, FontStretch, FontStyle, FontWeight, Foreground

There might be more I haven't mentioned yet, feel ffree to add to this list...

Thursday, July 05, 2007 10:15 AM by rudi

# Under the hood: Dependency Properties

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Tuesday, July 10, 2007 4:40 PM by DotNetKicks.com

# re: Under the hood: Dependency Properties

> .NET Framework 3.0 added a quick way to define a property

> public bool IsEmpty

> {

>    get;

>    set;

> }

I think this might be only in C# 3.0 / VS2008

Thursday, August 23, 2007 7:44 PM by MarkT