Geeks With Blogs
Imran Shaik Silverlight Quintessential Rambling

This  is  written to explain Dependency Properties in general as they are available in .NET Framework 3.0 but specifically targeting Silverlight 2.0, in most places effort has been placed to  explain the differences in Dependency Properties in WPF and Silverlight (With Silverlight perspective). But all examples are for Silverlight.

What is Dependency Property?

Dependency properties are new addition to .NET Framework 3.0, Dependency properties are completely new implementation of properties, all programmers are familiar with properties but Dependency properties have a significant amount of added value. They use a sophisticated storage and support higher level features such as property value change notification, property validation, property coercion, property metadata and default property value inheritance. Dependency properties can hold an optional default value, and can propagate the default value down the element tree.

Simply put, a Dependency Property is like any other property but can hold a default value, with built in mechanism for property value validation and automatic notification for changes in property value ( for anyone listening to property value - especially UI)  and any binding in Silverlight is to binded to a Dependency Property.

Dependency Properties Features:

  • Root class must be inherited from UIElement or DependencyObject (Eg., Controls, User Controls, Windows (WPF), or any class derived from UIElement (Button, List, Slider etc.))
  • Dependency Properties have to be registered using DependencyProperty.Register method.
  • Since DependencyProperty.Register is a static (C#) / Shared (VB.NET) method, all dependency properties should also be static/Shared fields, also the property changed callback methods should be static/Shared methods.
  • Any property must be a dependency property if the property is being binded to.
  • By convention, all Dependency Property fields should include the word “Property” at the end of the property name (e.g., for property Value, the Dependency Property name should be ValueProperty).

Defining and Registering a Dependency Property:

While working with .NET 3.0/.NET 3.5 Framework (WPF, Silverlight) you’ll spend more time using Dependency Properties instead of defining them, most of the time you won’t even realise you are using a Dependency Property, but you should be able to create and register Dependency Properties as they are key in designing custom controls, or if you wish to add additional properties for binding, animation or other UI features that would otherwise be not supported.

The syntax of defining a Dependency Property is different from traditional Properties, however features mentioned above should always be remembered while defining Dependency Properties.

Defining Syntax:

VB.NET

Public Class FrameworkElement
    Inherits UIElement

    . . . 
    Public Shared ReadOnly ValueProperty As DependencyProperty

    . . . 

End Class

C#

public class FrameworkElement : UIElement
{

    . . . 

    public static readonly DependencyProperty ValueProperty; 

    . . . 

}

Defining a dependency property is only the first step, in order of the Dependency Property to be used, it should be registered, the registration process also initialises a DependencyObject. 

The Framework ensures that the DependencyProperty objects is not instantised directly since DependencyObjects don’t have public constructors. Hence DependencyObject can only be initialised by using static/Shared DependencyProperty.Register method.

The keyword “Readonly” in the above definition means that the property can only be registered in the static (C#) / Shared (VB.NET) constructor of the class and once registered in can’t be changed(registration) or re-register hence it is readonly, and it doesn’t make the Dependency Property readonly, only that it can’t be reregistered.

Registering Dependency Property

To register the dependency property defined above we have to put them in static/Shared Constructor since they are declared as readonly. 

VB.NET

Public Class FrameworkElement
    Inherits UIElement


    Public Shared ReadOnly ValueProperty As DependencyProperty

    Shared Sub New()
        ValueProperty = DependencyProperty.Register("Value", GetType(Integer), GetType(FrameworkElement), Nothing)
    End Sub


End Class

C#

public class FrameworkElement : UIElement
{

    public static readonly DependencyProperty ValueProperty;

    static FrameworkElement()
    {
        
        ValueProperty = DependencyProperty.Register("Value", typeof(int), typeof(FrameworkElement), null);
    }

}

In Silverlight 2.0, static/Shared method of DependencyProperty.Register  takes 4 parameters, there are no overloads available as they are in WPF. 

  1. Name of the property to be registered
  2. Data type of the Dependency Property being registered
  3. Owner (Data type of parent) of the Dependency Property being registered (typically the root class). 
  4. Metadata of the Dependency Property (Optional by specifying null (C#)/Nothing (VB.NET))

Note: You can also define and register DependencyProperty at the same time but you can optionally exclude “readonly” from the DependencyProperty definition.

C#: public static DependencyProperty ValueProperty = DependencyProperty.Register(…);

VB.NET: Public Shared ValueProperty As DependencyProperty = DependencyProperty.Register(…)

 

Reading and Writing Dependency Property values

Once a Dependency Property is defined and registered, you can’t use these properties as traditional .NET properties, Dependency Properties values should be set/get in a different way.

Getting Dependency Property Value

The beauty of Dependency Properties is that it can be used or called by any class or object where the Dependency Property parent class is available (specifically the default value) , even if you haven’t locally defined the parent class, for example you can get the default value down the tree of the parent or child of the class without first initialising the class. The only condition is that the parent class assembly should be made available.

The method to be used to get the value of a Dependency Property is GetValue()

VB.NET  

GetValue(FrameworkElement.ValueProperty)

C#

GetValue(FrameworkElement.ValueProperty); 

Setting Dependency Property Value

Similar to getting the property, setting the property value of a Dependency Property should be done by a method SetValue(), the property name should be with reference to the owner class along with the DependencyProperty.

VB.NET

SetValue(FrameworkElement.ValueProperty, 4)

C#

SetValue(FrameworkElement.ValueProperty, 4);

 

 

 

Property Wrapper

There is a limitation on the methods GetValue and SetValue, in order for a DependencyProperty to be set/get a value the class setting/getting should also be inherited from DependencyObject/UIElement, since GetValue and SetValue methods are inherited from DependencyObject class. In order to overcome this and the simplify the use of Dependency Properties and to make easy and transparent transition (in using) between Dependency Property and Attached Property, Property wrappers are used and are defined within the same class as the definition of Dependency Property.

VB.NET

Public Property Value() As Integer
    Get
        Return GetValue(ValueProperty)
    End Get
    Set(ByVal value As Integer)
        SetValue(ValueProperty, value)
    End Set
End Property

C#

public int Value
{
    get
    {
        return (int) GetValue(ValueProperty);
    }
    set
    {
        SetValue(ValueProperty, value);
    }
}

 

By using property wrappers now the transition between Dependency Properties and normal Properties is transparent, we can carry on using Dependency Properties like we use Properties, in property wrappers any other code like raising an event or validating values should not be included, the wrapper automatically ignores any other code within the wrapper and only looks for SetValue/GetValue methods.

Dependency Property Metadata 

In WPF Dependency Property Metadata is very complex and there are many overloads available but in Silverlight 2.0, Dependency Property Metadata only support two objects, with a maximum of three overloads

  1. Default Value
  2. Property Changed Callback
  3. Default Value, Property Changed Callback

VB.NET

Public Class FrameworkElement
    Inherits UIElement

    Public Shared ReadOnly ValueProperty As DependencyProperty

    Shared Sub New()

        ValueProperty = DependencyProperty.Register("Value", GetType(Integer), GetType(FrameworkElement), _
                  New PropertyMetadata(0, New PropertyChangedCallback(AddressOf FrameworkElementValueChanged)))

    End Sub

    Shared Sub FrameworkElementValueChanged(ByVal sender As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)

    End Sub
End Class

C#

public class FrameworkElement : UIElement
{

    public static readonly DependencyProperty ValueProperty;

    static FrameworkElement()
    {
        
        ValueProperty = DependencyProperty.Register("Value", typeof(int), typeof(FrameworkElement), 
            new PropertyMetadata(0, new PropertyChangedCallback(FrameworkElementValueChanged)));
    }

    static void FrameworkElementValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {

    }

} 

In above mentioned examples, the ValueProperty will hold a default value of 0  and every time the value is changed (except for setting the default value), a property changed callback method is invoked (in this example, FrameworkElementValueChanged), the property changed callback should also be a static/Shared method/function, which take two parameters – DependencyObject and DependencyPropertyChangedEventArgs. (This callback method is not generated automatically so the parameters should be remembered for future references).

The DependencyPropertyChangedEventArgs, holds three properties

  1. NewValue
  2. OldValue
  3. Property

The NewValue is the requested value to be changed, the old value is the current value that will be replaced and the property is the identifier of the property requested to be changed, if property changed callback is defined the property value will be changed as soon as the callback method is exited, or in case of a function when a true value is return (to accept the new value) or false (to reject the new value and revert the value to old value).

VB.NET 

Shared Function FrameworkElementValueChanged(ByVal sender As DependencyObject, _
                                            ByVal e As DependencyPropertyChangedEventArgs) As Boolean
        Dim FwE As FrameworkElement = CType(sender, FrameworkElement)
        Dim NVal As Integer = CType(e.NewValue, Integer)
        Dim OVal As Integer = CType(e.OldValue, Integer)

        If (NVal < FwE.Minimum) Then
            Return False
        Else
            Return True
        End If

        If (NVal > FwE.Maximum) Then
            Return False
        Else
            Return True
        End If

 End Function

C#

static bool FrameworkElementValueChanged(DependencyObject sender, 
            DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement FwE = sender as FrameworkElement;
            int NVal = (int)e.NewValue;
            int OVal = (int)e.OldValue;

            if (NVal < FwE.Minimum) return false; else return true;

            if (NVal > FwE.Maximum) return false; else return true;

        }

Since the callbacks methods are also static, you’ll have to cast the sender as the parent class in order for you to use the other methods/properties within the class.

In the above example, if the requested value change is within the Maximum and Minimum value then the new value is accepted or else it is rejected (Note: The callback method being called is a boolean function), this is where you can do your additional updates to any objects depending on the property value or raise events. 

Property Coercion

In WPF, Dependency Property metadata also includes a separate method for property coercion, when a value change is requested, it first execute property coercion callback which can modify the supplied value with property coercion callback, and then property changed callback is called. In Silverlight, Dependency Property metadata is very simple, as mentioned above there is no property coercion callback available, but you can get around that and coerce property value within the property changed callback.

VB.NET

Shared Sub FrameworkElementValueChanged(ByVal sender As DependencyObject, _
                                        ByVal e As DependencyPropertyChangedEventArgs)
    Dim FwE As FrameworkElement = CType(sender, FrameworkElement)
    Dim NVal As Integer = CType(e.NewValue, Integer)
    Dim OVal As Integer = CType(e.OldValue, Integer)

    If NVal < FwE.Minimum Then
        FwE.Value = FwE.Minimum
    End If

    If NVal > FwE.Maximum Then
        FwE.Value = FwE.Maximum
    End If

End Sub

C#

static void FrameworkElementValueChanged(DependencyObject sender, 
    DependencyPropertyChangedEventArgs e)
{
    FrameworkElement FwE = sender as FrameworkElement;
    int NVal = (int)e.NewValue;
    int OVal = (int)e.OldValue;

    if(NVal < FwE.Minimum)
    {
        FwE.Value = FwE.Minimum;
    }

    if(NVal > FwE.Maximum)
    {
        FwE.Value = FwE.Maximum;
    }

}

The above property changed callback is a method instead of a function, where if the requested value change falls beyond the acceptable value it will coerce the value to an acceptable value, in this example if a valid value change is requested and if it exits the method without any change then the value will be accepted.

Limitations of Dependency Property in Silverlight 2.0

Silverlight 2.0 have a very limited control and usage with Dependency Properties, and their existence in Silverlight is only to enable any value to be able to bind to the property rather than provide anything significant. There are many limitation on user defined Dependency properties in Silverlight that its almost unusable in normal circumstances, but in case of user defined custom controls it becomes a compulsion to use dependency properties since binding can only be done to a dependency property and a well built custom control should support binding.

The problem with user defined Dependency Property in Silverlight 2.0 is with the ability to be bind with itself. It can bind to a Dependency Property of another class (if that class is explicitly mentioned as data context). This inability of Dependency Properties renders the use of Dependency Properties in Silverlight to almost useless. Normally (in WPF) you can use a Dependency Property just like a Attached Property, even binding is done with relative easy and user will remain transparent to anything that goes beyond, and by default the context is its own class so there is no problem with binding with itself, but in Silverlight 2.0, Dependency Properties behave differently and should only be used in exceptional circumstances (designing custom controls) and understanding the limitations.

If you are considering using a Dependency Property only to notify changes to property value to UI then you can  use interface System.ComponentModel.INotifyPropertyChanged and use normal Properties instead of Dependency Properties, for example.

VB.NET

Imports System.ComponentModel
Public Class FrameworkElement Implements INotifyPropertyChanged

    Public Event PropertyChanged As PropertyChangedEventHandler _ 
Implements INotifyPropertyChanged.PropertyChanged Private _Value As Integer Public Property Value() As Integer Get Return _Value End Get Set(ByVal value As Integer) If _Value <> value Then _Value = value RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Value")) End If End Set End Property End Class

C#

using System.ComponentModel;
namespace Elements
{
   public class FrameworkElement : INotifyPropertyChanged
   {

       public event PropertyChangedEventHandler PropertyChanged;

       private int _value;

       public int Value
       {
           get
           {
               return _value;
           }
           set
           {
               if (_value != value)
               {
                   _value = value;
                   PropertyChanged(this, new PropertyChangedEventArgs("Value"));
               }
           }
       }
   }
}

Note: Since in Silverlight an object can’t be binded to any Dependency Property within its own class, its fair to assume that all Dependency Properties in Silverlight are Public.

Microsoft hasn’t explained the limitation on usage of Dependency Properties in Silverlight 2.0, as far as I understand it has to do with the cross platform framework of Silverlight 2.0. But  hopefully Silverlight 3.0 will support advanced Dependency Property options, at least those that we already expect from Silverlight 2.0.

More on Dependency Properties and  Binding, how and why they both are related to each other in next topic to follow - Understanding: Binding in Silverlight.

Posted on Wednesday, December 24, 2008 8:49 AM Silverlight | Back to top


Comments on this post: Understanding: Dependency Properties in Silverlight

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
I don't think your definition of Attached properties agrees with the one Microsoft has. See http://msdn.microsoft.com/en-us/library/ms749011.aspx

Left by Mark on Dec 24, 2008 7:53 PM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
Your second example under Dependency Property Metadata will return before evaluating the last expression if I've understood this correctly:

i.e. this line will cause false/true to be returned:

if (NVal < FwE.Minimum) return false; else return true;

and this line won't execute:

if (NVal > FwE.Maximum) return false; else return true;
Left by Guy Ellis on Dec 29, 2008 5:16 PM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
Hey Imran,

Great article. One other thing to add though:

You mentioned that "Note: You can also define and register DependencyProperty at the same time but you have to exclude “readonly” from the DependencyProperty definition."

You actually can keep the readonly in the DP definition when defining and registering at the same time.

D
Left by D'Arcy from Winnipeg on Dec 30, 2008 6:49 PM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
Mark:

Thanks for bringing it to my notice I'll update it accordingly

Guy Ellis:
Thanks for the comment, the example is only to show the working of property changed callbacks and nothing more.

D'Arcy:
Thanks for it, althought the readonly clause is to stop the DP from re-registering, you are right you can register DP as readonly and you can infact register it in a single line I was just trying to simplyfly it for first time users.
Left by Imran Shaik on Jan 01, 2009 5:55 PM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
This article seems to be very much like portions of "Pro Silverlight 2 in C# 2008" by Matthew MacDonald, especially p98. Either you are lifting from him or he's lifting from you.
Left by Mark on Feb 20, 2009 1:20 AM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
Thank you for this article. It's really helpful for me.
Left by pwr on Jul 01, 2009 4:12 PM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
Good Article.
Left by nag on Sep 25, 2009 2:59 AM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
Cool article.
(@Mark: if you know something it is because you read it somewhere. Our friend is not saying that one day after drinking his coffee he created all the things in the paper. He read these information somewhere, surely. But you can be sure Matthew MacDonald also read it somewhere before writing his book (certainly from one of the numerous MS papers) !!! Knownledge does not belong to someone in particular. Whe are speaking about _technical_ knowledge, not about a new symphony nor a very creative work. Just pieces of technical info that belongs to nobody...).
Left by olivier on Oct 05, 2009 2:54 PM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
One think about the paper : SL does not accept function Callback just simple methods. So using a bool function to validate the value does not work.
For the coercion there is a BIG problem with your method : you set a new value by code this is meaning you will break any existing databinding (value set by code has the priority over xaml databinding).
So the principles you are presenting are valid but none of you solutions are working...
Left by olivier on Oct 23, 2009 2:23 AM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
yea the article is quite usefull but you will give full example sample, then it adds more importants.
Left by Ram Prawesh on Feb 11, 2010 6:55 PM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
Explanied briefly about dependancy property at the following post:
http://blog.subhendu.info/index.php/dependency-property/

Have a look and you may find few basic concepts about C#,.NET and Silverlight
Left by Subhen on Jun 15, 2010 11:24 PM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
This is a very helpful post, i hope this really helps me to complete my project.
Left by Yachtcharter Griechenland on Oct 21, 2010 5:38 PM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
Dependencies are also explained in the .Net framework 4.0 but it is the case here that how can we implement it for validation, such as required field validation
Left by apple iphone application develop on Apr 19, 2011 1:04 AM

# re: Understanding: Dependency Properties in Silverlight
Requesting Gravatar...
Thanks for describing the dependency property. It's actually very interesting. good stuff
Left by tum on Apr 28, 2011 8:34 PM

Your comment:
 (will show your gravatar)


Copyright © Imran Shaik | Powered by: GeeksWithBlogs.net