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

Share

About Jesse Liberty

Jesse Liberty is an independent consultant and programmer with three decades of experience writing and delivering software projects. He is the author of 2 dozen books and multiple Pluralsight courses, and has been 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 Xamarin Certified Mobile Developer and a Xamarin MVP, Microsoft MVP and Telerik MVP.
This entry was posted in Data, Essentials, Languages, Mini-Tutorial, Patterns & Skills, WindowsPhone and tagged . Bookmark the permalink.

11 Responses to Dependency Properties

  1. dribbble.com says:

    E-book readers Since reading is a favorite pastime for most people,
    these gadgets are in great demand today. For those who want to give something
    truly exclusive and precise, watch can be a perfect choice.
    Gifts are a great way expresses our love, affection, care and
    respects.

  2. Annmarie says:

    I love Pandora because I can customize my r / c and tune in to songs that I actually like.

    All of such models are certain to provide one of the most excellent sound quality to
    your video games. Some wireless systems can transmit full 1080p high-definition signals.

  3. One method to speed machine general performance is to use a registry scanner many computer specialists believe.
    She used to go through in details the photos of her childhood.
    Children and grandchildren can be shown the photographs of the wedding ceremony.

  4. funny videos says:

    There are tons of internet users out there looking for a website like yours, good article

  5. WPF beginner says:

    I’m very new to WPF, so this may be a silly question, but why is this so verbose? Is there any reason why there’s no API (or compiler) support for this? Why can’t we write something like:

    [Dependency]
    public bool Valuable {get; set;}

  6. route says:

    where do i write these DP in MVVM approach, in the code behind or in the view model?

  7. Pete Barber says:

    >>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.

    Is this the case? Doesn’t it just boil down to a map added DependencyObject and is far above C# and the CLR?

  8. Pingback: Understanding dependency properties « World Wide Code

  9. Pingback: Dependency Properties – www.nalli.net

  10. Great post. Observer pattern done easy 😀
    But I have a question?
    Can i register multiple observers?
    Or will I have to go around and notify the other listeners from the 1 registered observer?

    • John Tasler says:

      var descriptor = DependencyPropertyDescriptor.FromProperty(…) and then:
      descriptor.AddValueChanged(someObject, EventHandler) will do the trick in WPF. It seems, however, that SL4 still doesn’t have this pattern.

      Does anyone know of an equivalent for SL4?
      Is DependencyPropertyDescriptor and its events being added to SL5?

Leave a Reply

Your email address will not be published.