Dependency Property and Dependency Object: Difference between Dependency Property and CLR Property

Dependency Property and Dependency Object: Difference between Dependency Propery and CLR Property

Dependency properties belong to one class but can be used in another. Consider the code snippet below:

 

Height and Width are regular properties of the Rectangle. But Canvas.Top and Canvas.Left are dependency properties as they belong to the Canvas class. It is used by the Rectangle to specify its position within Canvas.

Dependency Property is defined as static. So Dependency Property is maintained at class level. The wrapper class which can create a Dependency property is called a DependencyObject. To work with dependency property, you must derive the class from DependencyObject

Difference between Dependency property and CLR property

CLR property is just a wrapper around private variables. It uses Get / Set methods to retrieve and store value of a variable into it. CLR property gives you only one block in which you can write code to invoke whenever a property is get or set. Hence CLR property system is fairly straightforward.

On the other hand, the capabilities of Dependency property system is huge. The idea of Dependency property is to compute the value of the property based on the value of other external inputs. The external inputs might be styles, themes, system properties, animations, etc. So, you can say a dependency property works with most of the WPF inbuilt features that were introduced.

Advantages of Dependency Property

1. Property Value Inheritance: By Property Value Inheritance, we mean that value of a Dependency property can be overridden in the hierarchy in such a way that the value with highest precedence will be set ultimately.

2. Data Validation: We can impose Data Validation to be triggered automatically whenever the property value is modified.

3. Participation in Animation: Dependency property can animate. WPF animation has lots of capabilities to change value at an interval. Defining a dependency property, you can eventually support Animation for that property.

4. Participation in Styles: Styles are elements that define the control. We can use Style Setters on Dependency property.

5. Participation in Templates: Templates are elements that define the overall structure of the element. By defining Dependency property, we can use it in templates.

6. DataBinding: As each of the Dependency properties itself invoke INotifyPropertyChanged whenever the value of the property is modified, DataBinding is supported internally. 

7. CallBacks: You can have callbacks to a dependency property, so that whenever a property is changed, a callback is raised.

8. Resources: A Dependency property can take a Resource. So in XAML, you can define a Resource for the definition of a Dependency property.

9. Metadata overrides: You can define certain behavior of a dependency property using PropertyMetaData. Thus, overriding a metadata form a derived property will not require you to redefine or re implementing the whole property definition.

10. Designer Support: A dependency property gets support from Visual Studio Designer. You can see all the dependency properties of a control listed in the Property Window of the Designer.

How To Define a Dependency Property

public static readonly DependencyProperty MyCustomProperty = 
DependencyProperty.Register("MyCustom", typeof(string), typeof(Window1));
public string MyCustom
{
    get
    {
        return this.GetValue(MyCustomProperty) as string;
    }
    set
    {
        this.SetValue(MyCustomProperty, value);
    }
}

In the above code, I have simply defined a Dependency property. Dependency property is declared as static and maintained in class level, so you may say Class A to have a property B. So property B will be maintained to all the objects that class A have individually. The Dependency property thus creates an observer for all those properties maintained by class A and stores it there. Thus it is important to note that a Dependency property should be maintained as static.

The naming convention of a dependency property states that it should have the same wrapper property which is passed as the first argument. Thus in our case, the name of the Wrapper "MyCustom" which we will use in our program should be passed as the first argument of the Register method, and also the name of the Dependency property should always be suffixed with Property to the original Wrapper key. So in our case, the name of the Dependency Property is MyCustomProperty. If you don't follow this, some of the functionality will behave abnormally in your program.

It should also be noted that you should not write your logic inside the Wrapper property as it will not be called every time the property is called for. It will internally call the GetValue and SetValue itself. So if you want to write your own logic when the dependency property is fetched, there are callbacks to do them.

Sources: