Dependency Properties

Windows Phone Tutorial

Dependency properties are like the sewers, electric wires and pipes running under the streets of a big city. You can ignore them, you can even be oblivious to their existence, but they make all the magic happen and when something breaks you really want to understand them.

Before we begin exploring Dependency Properties, let’s review Properties themselves. To do that, we go back into the dark early days of C++ when what we had available in a class were methods and  member variables (fields).

When I was a boy, there were no properties, VCRs or digital watches… 

Data Hiding

Back in these dark days, we wanted to store values in fields, but we didn’t want clients (methods that use our values) to have direct access to those fields (if nothing else, we might later change how we store the data).  Thus we used accessor methods. 

The accessor methods had method semantics (you used parentheses) and so data hiding was explicit and ugly. You ended up with code that looked like this:

int theAge = myObject.GetAge();

 

which just seems all wrong , what you wanted was

int theAge = myObject.age;

 

Field Syntax with Method Semantics

Enter properties.  Properties have the wonderful characteristic of looking like a field to the consumer, but looking like a method to the implementer. Now you can change the way the Property is “backed” without breaking the consumer, but the consumer gets the right semantics. Nice.

The class with the property looks like this

private int _age;
public int Age { get { return _age; } set { _age = value; } }

 

Age is the property, _age is the backing variable.  The consumer can now write

int theAge = myObject.Age;

 

Yet, Age is actually a property and so you can put anything you like in the getter, including accessing a database or computing the age.

Note, by the way that this idiom of just having a backing variable and getting and setting its value is so common that automatic properties were invented to save typing. Thus, the private  field and public property above could have been written with this single line:

public int Age { get; set; }

 

The compiler turns this single statement into a declaration of a private backing variable, and a public property whose get returns that backing variable, and whose set, sets that variable.

Dependency Propoerties

Dependency properties are an extension to the CLR and to C#, and were created because normal properties just don’t provide what we need: declarative syntax that is fast enough to support animation and that will support data binding

In short, what was needed was a system that could establish the value of a property, at run time, based on input from a number of sources (e.g., the current value of other properties, rapidly changing animation values, etc.).

A key value of the Dependency Properties system was the ability to build properties that automatically notify any registered interested party each time the value of the property changes.  This free, painless and automatic implementation of the observer pattern is tremendously powerful and greatly reduces the burden on the client programmer (in fact, the data-binding system depends on it!).

This means that if you bind numerous controls to dependency properties, your controls are guaranteed to be notified any time the value of the bound  properties change, without your writing a line of code.

In exchange for these capabilities you pay the price of the added complexity of a second type of properties overlaid on top of the inherent properties of the language.  In addition, some of your properties are really just wrappers to the Dependency Property.  What that means is that the backing value for some of your properties is not a member variable or a value in a database or a computation, but a Dependency Property.  That takes a little mind-share

Here’s what that looks like in code:

public bool Valuable
{
   get { return (bool) GetValue( ValuableProperty ); }
   set { SetValue( ValuableProperty, value ); }
}

A pretty standard get and set, except that you access your backing variable using GetValue and SetValue to get and set the value of a Dependency property named ValuableProperty (and that is the idiom, the CLR property name + the word Property = the name of the DP, thus Valuable + Property = ValuableProperty.

The declaration of the DP itself is much weirder,

public static readonly DependencyProperty ValuableProperty =
    DependencyProperty.Register(
       "Valuable",
       typeof( bool ),
       typeof( MyCustomControl ),

  new PropertyMetadata( new PropertyChangedCallback(   
      MyCustomControl.OnValuablePropertyChanged ) ) );

Let’s  break this down. The first line declares my object (which is really a reference to a DependencyProperty) as public; it must be static and readonly, and its type is DependencyProperty and its name (identifier) is ValuableProperty.

We set that reference to what we’ll get back by calling the static Register method on the DependencyProperty class. Register takes four arguments:

  1. The name of the dependency property wrapper
  2. The type of the DP being registered
  3. The type of the object registering it
  4. The Callback

The Callback is of type PropertyMetaData. You can imagine a world in which there are various pieces of MetaData for the DependencyProperty. At the moment, however, in Silverlight, there is only one: the callback.

The constructor for the PropertyMetaData takes an object of type PropertyChangedCallback which will be called any time the effective property value of the DP property changes.  We pass it a reference to the method to call (which equates to a callback).

The net of all of this is that we present to the world a CLR property (Valuable) which is in fact backed by a DependencyProperty which will call back to the method OnValuablePropertyChanged any time the effective value of the property changes.

The callback method will take two arguments:

  • A DependencyObject (the control)
  • An object of type DependencyPropertyChangedEventArgs

Typically you’ll cast the first argument to be the type of the control that contains the property, and you’ll cast the NewValue property of the DependencyPropertyChangedEventArgs object to the DependencyProperty that changed. You can then take whatever action you need to based on the change in the DP’s value

public class MyCustomControl : Control
{
   public static  readonly DependencyProperty 
      ValuableProperty = DependencyProperty.Register(
       "Valuable",
       typeof( bool ),
       typeof( MyCustomControl ),
       new PropertyMetadata( new PropertyChangedCallback( 
           MyCustomControl.OnValuablePropertyChanged ) ) );

   public bool Valuable
   { 
      get { return (bool) GetValue( ValuableProperty );}

      set { setValue( ValuableProperty, value );}
   }

 

   private static void OnValuablePropertyChanged( 
       DependencyObject d, 
       DependencyPropertyChangedEventArgs e )
   {
      MyCustomControl control = d as MyCustomControl;

      bool b = (bool) e.NewValue;
   }
}


 

This posting is based, in part, on my postings about Dependency Properties from 2008

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in Data, Essentials, Languages, Mini-Tutorial, Patterns & Skills, WindowsPhone and tagged . Bookmark the permalink.

9 Responses to Dependency Properties

Comments are closed.