Dependency property is a term that left me baffled for a long time. But I finally understand them and in this article I'll try to explain what they actually are.
CLR Properties:
Before talking about dependency properties, let's talk about CLR properties for a while. Look at the code below.
CLR Properties:
Before talking about dependency properties, let's talk about CLR properties for a while. Look at the code below.
public class A { private int _var; public int Var { get { return _var; } set { _var = value; } } }
Var is a CLR property whose value can be get/set and _var is the private variable that is used to the store the Var property value in between the uses. The process of storing a property value in a private variable is called backing.
The whole point of using a property rather than simply exposing a public variable is to validate and transform its value using getters and setters.
Dependency Properties:
The dependency properties are basically an upgrade to the CLR properties. In case of CLR, a property is stored in a private variable and accessed using get/set methods, so the next logical step would be to create object based properties.
You could create a class and name it ObjectProperties and give it necessary methods along with getters/setters to make it work as a property. What's the advantage in it, you ask?
Because of being an object based property, we could provide facilities such as reacting to events on other objects and being able to generate events when a property changes. Making object-based properties is a good but complex idea and implementing it would require quite a bit of work.
Well, the good news is we don't have to do the work because that's what dependency properties are. Dependency properties are object-based properties that offers lots of additional features and behaviors as compared to the basic CLR properties.
The most commonly used feature of dependency properties is data binding. It allows you to bind a dependency property to another in such a way, that a change in the value of one, changes the other. It is made possible because of the built-in change notification mechanism of the dependency properties. A callback is registered to notify whenever there is a change in the value of property.
So, now that we understand what dependency properties are and how they work let's try to declare one. You can do that by typing propdp and pressing the Tab key twice in visual studio.
public int MyProperty { get { return (int)GetValue(MyPropertyProperty); } set { SetValue(MyPropertyProperty, value); } } // Using a DependencyProperty as the backing store for MyProperty.
//This enables animation, styling, binding, etc... public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register("MyProperty", typeof(int),
typeof(ownerclass),
new PropertyMetadata(0));
The first thing you will notice is that even a dependency property has a wrapper. And second is the use of static keyword. Now, the trick is, that the declaration of the dependency property is static and not it's value. A dependency property is declared through a static method which returns us a key(an identifier) of type DependencyProperty that we will be able to pass to GetValue and SetValue to get and set the property on a specific DependencyObject.
The declaration is made static because the same identifier will be shared by all the instances of the DependencyObject, however when you set the value of a DependencyProperty by calling the SetValue on a DependencyObject instance, then each instance of the DependencyObject on which the SetValue is called will store its local value of the property. The value of a dependency property is not stored in a field of your object but in a dictionary of keys and values provided by the base class DependencyObject. The key is the identifier and the value is the value you want to set. Also the value of a DependencyProperty is resolved dynamically when calling the GetValue(). It checks if a local value is available, if yes it reads it directly from the dictionary, if not it looks for an inherited value and if that is also not available, it uses the default value defined in the property metadata.
Another advantage of dependency properties is that storage is only needed for properties whose value is assigned. It almost never happens that we assign all the properties of a particular control, a lot of properties are just left at their default values. In case of dependency properties the default values are stored as meta-data related to the property and do not require any memory per control instance if the property remains unassigned.
I hope that above article made sense to you and after reading it you finally understand dependency properties.
No comments:
Post a Comment