Dependency Properties
When I started working on the WPF about three years ago (earlier I was working on ASP.NET), the first thing I encountered was a strange kind of property. First of all I was new to Windows development and on top of that I started with WOF itself. I was always curious about how Dependency Properties (DP) work. Though I now understand very well how they work I will now try to provide a brief explanation of dependency properties and how they work.
.NET has always been enriched with the property system. Properties help us to encapsulate the information of the class from the outer world. Though it can be big on the memory footprint for the class. Suppose I have a class TextBox and I have defined a property known as BackGround. Now whenever I am creating the instance of the class, the memory on the heap will be allocated based on the properties and member variables of the class that will eventually increase the memory footprint for the class. So for example, if we have 100 objects with 100 CLR properties of type int each, then we are using 10000 ints worth of memory even if all those have the same default value (0). Here is where dependency properties are relevant. The Dependency Property has been included in the framework keeping this point in mind. Dependency properties are static in nature. That means that they have some default value stored in the Dependency Property system. The Dependency Property system consists of a dictionary that is popularly known as a “property bag”. This is the same default value that we provide for the property when creating them.
As soon as we are clear about this point a question comes to our mind of why they are called “Dependency”. The implementation of these properties depends on the precedence of the value they are getting their values from. As discussed earlier they have some default value assigned when creating them, so that is the last in the hierarchy from which they can get the value. The hierarchy of the sources from which the Dependency Property can get its value are as in the following.
- Property system coercion
- Active animations, or animations with a Hold behavior
- Local value
- TemplatedParent template
- Style triggers
- Template triggers
- Style setters
- Theme style
- Inheritance
- Default value from Dependency Property metadata
So from the preceding discussion we can derive the one conclusion, that a DP doesn't ever have its own value. Its value always on the number of outside factors or it gets its value from one of the sources in the hierarchy. That's the reason we call it a “Dependency” property.
That was not all the basics of dependency properties. Apart from that there are many intricacies that we will discuss in a future article.
Implementation
Now I want to show you with a code example how a Dependency Property can be used. The basic requirement for having a Dependency Property in your class is that the class should inherit from DepedencyObject that in turns provides the mechanism for storing and retrieving the dependency values.
I have declared a Dependency Property BirthdayYear as follows. Kindly note that whenever we declare a DP .Net framework attached “Property” to the property name then something happens.
- public int BirthYear
- {
- get { return (int)GetValue(BirthYearProperty); }
- set { SetValue(BirthYearProperty, value); }
- }
-
-
- public static readonly DependencyProperty BirthYearProperty =
- DependencyProperty.Register("BirthYear", typeof(int), typeof(BirthdayYear), new PropertyMetadata(1983));
Listing 1
Here I want to state explicitly a few things. As you can see in the preceding listing the DP that I have declared is of type int. The framework uses the Register method to register the DP in the DP property subsystem with the default value 1983. Since it is quite difficult to remember this syntax of declaring dependency properties, the .Net framework provides a code snippet to help us with that. As you will type propdp in the Visual Studio you will get an option to create the DP as shown in the following figure:
1. After this step you need to press tab twice and you will get the code for declaring a DP. There you need to provide what type your Dependency Property would be, the owner of the Dependency Property. In other words the class in which the property is defined. Now I want to use the User Control that has defined this Dependency Property in my main window. The XAML for which is shown below:
- <local:BirthdayYear x:Name="birthdayYear"></local:BirthdayYear>
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto"></ColumnDefinition>
- <ColumnDefinition Width="Auto"></ColumnDefinition>
- </Grid.ColumnDefinitions>
- <TextBlock Text="{Binding BirthYear, ElementName=birthdayYear}" Grid.Column="0" Height="50"></TextBlock>
- <Button Content="Change Value" FontSize="20" Click="OnChangeValue" Grid.Column="1" Height="50"></Button>
- </Grid>
Listing 2
2. Now wherever I run my application my main window will be shown with a textblock that shows the default value of the DP that is “1983”.
3. As shown in Listing 2 I have a Click event for the Button that increases the value of the DP every time it is clicked.
- private void OnChangeValue(object sender, RoutedEventArgs e)
- {
- ++birthdayYear.BirthYear;
- }
As soon as the button is clicked the value is increased in the textblock. How does this happen? This has happened using the Dependency Property system that listens to the change notification of the property that has been registered as a DP.
I have attached the code for the project along with this article so that you can play with it.
Kindly provide your feedback about the article.