Wednesday 8 April 2015

Dependency Property

Before discussing what a dependency propriety it's good to go over what a regular property is; A property is an accessor to a field, that is the public property PropertyName {get; set;} is actually used to retrieve or set a private backing field, think of it as a gatekeeper; when all you see is:


public string Name { get; set; }

what it actually complies into is


private string _name;

public string Name
{
    get { return _name; }
    set { _name = value; }

}

Well at the c# level once it goes into msil then that's another story.

This paradigm allows you to do validation on the setting of the backing field or sanitation on the getting of the backing field.

Now there is a drawback to such properties, and that is that the take up memory, not a big deal right? well let's say you have a control that has 50 properties, each on of them takes up memory, so if you now have multiple instances of this control (let's say a button or a textbox) well then that's 50 times however many instances of that control you have on your form; as you can imagine these properties will chew through your memory. Worse yet how many of these properties do you change from their default values, 3? maybe 5?

In come Dependency Properties, you can think of dependency properties as static if they are left in their default state, that means for example: all buttons share the IsEnabled property if it's left in it's default value of true, only when the value is changed on a control is the dependency property stored.

Any class that wants to use a dependency property must inherit from DependencyObject, inside of this baseclass there exists the mechanism that stores all of the customized values in a key value dictionary, Internally when you call the GetValue(DependencyProperty) function on a dependency property first the dictionary is checked for a set local value, if one does not exist, the mechanism walks up the logical tree looking for an inherited value (ie something like font) then finally if it walks all the way up the logical tree it takes the default static value of the dependency property.

As mentioned Dependency Properties allow controls to use inheritance; often when you set properties such as font or color you want them to be inherited by the controls children, as mentioned if no defined local value exists for a Dependency Property it will next try to find the inherited value before defaulting to the static one.

Possibly the most advantageous benefit of Dependency Properties is Change Notification, when you declare a Dependency Property you pass in a callback that notifies you if the value is changed, this is utilized by DataBinding.

In Summary Dependency Properties bring Three Main advantages to the Table

  1. Change Notification: mainly used by animations to change values
  2. Reduced Memory Footprint: Static default values, allow you to share backing fields
  3. Value Inheritance: allow dependency Properties to inherit values from parent controls.

Let's take a deeper look,  now remember when I said that Dependency properties resolve to their local value, inherited value and then their default value? we'll I left 7 other things they could resolve to:
  1. Animation: the current animation that is being executed on your control. 
  2. Bound Value: the corresponding property bound to in a ViewModel 
  3. Local Value: a local value that is set in the xaml 
  4. Template Properties: values set in a control template 
  5. Custom Style Setter: a style that is specified in the resources of either your page or app 
  6. Default Style Trigger 
  7. Default Style Setter: A value that is defined at: "C:\Program Files (x86)\Windows Kits\8.1\Include\winrt\xaml\design" 
  8. Inherited Value: A value from a parent control that has the same Property 
  9. Default Value: the value specified when the Property is Registered
Now to declare a Dependency property look below

public int MyProp
{
    get { return (int)GetValue(MyPropProperty); }
    set { SetValue(MyPropProperty, value); }
}

// Using a DependencyProperty as the backing store for MyProp.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyPropProperty =
DependencyProperty.Register("MyProp"typeof(int), typeof(Exercise),new PropertyMetadata(0));

Visual studio has a propdb snippet to save you the trouble of memorizing this.

  1. The first parameter is the key associated with the dependency property it has to match the accessor Property name, 
  2. the second is the type that the property represents, 
  3. the third is the class that the dependency property is in, 

The third property is where the action happens, it has 5 constructors PropertyMetadata basically it has three potential parameters:

  1. Object: a default value for the Dependency property 
  2. PropertyChangedCallback: a delegate that get's called every time the property is changed. 
  3. CoerceValueCallback: allows you to set a boundary of values for your dependency properties

Finally you can also mark your dependency property as read-only, these are used to notify of things such as mouse over.