Introduction
A New Property System
Difference between Dependency Property and CLR Property
Advantages of Dependency Property
How To Define a Dependency Property
Defining Metadata for Properties
Note on CollectionType Dependency Property
PropertyValue Inheritance
Attached Properties
Conclusion
WPF comes with a lot of new features and alternatives that the normal Windows applications do not have. As we have already discussed some of the features of WPF, it's time to go a bit further to introduce other new features. After reading the previous articles of this tutorial, I hope you are more or less familiar with WPF architecture, borders, Effects, Transformation, Markup extensions, etc. If you aren't, please go through the series of articles as labelled:
WPF Tutorial: Beginning
[
^
]
WPF Tutorial: Layout-Panels-Containers & Layout Transformation
[
^
]
WPF Tutorial: Fun with Border & Brush
[
^
]
WPF Tutorial - TypeConverter & Markup Extension
[
^
]
WPF Tutorial - Dependency Property
[
^
]
WPF Tutorial - Concept Binding
[
^
]
WPF Tutorial - Styles, Triggers & Animation
[
^
]
So in this article, I am going to introduce you to a new property system that underlays the WPF property system. We will go further to introduce how easily you can use these properties to produce custom callbacks, create attached properties, apply animations and styles, etc. using the all new Dependency properties. Finally, we will discuss about Binding alternatives that were left behind in the previous article to finish it totally. I hope you will like this article as well as you did for all the tutorials that I provided.
Well, you must have been surprised to see this title. Yes, WPF comes with a completely new technique of defining a property of a control. The unit of the new property system is a Dependency property and the wrapper class which can create a Dependency property is called a
DependencyObject
. We use it to register a Dependency property into the property system to ensure that the object contains the property in it and we can easily get or set the value of those properties whenever we like. We even use normal CLR property to wrap around a dependency property and use
GetValue
and
SetValue
to get and set values passed within it.
This is almost the same as CLR property system. So, what are the advantages of the new property system. Let's see the difference between Dependency property and CLR property.
To work with dependency property, you must derive the class from
DependencyObject
as the whole observer which holds the new Property System is defined within the
DependencyObject
.
CLR property is just a wrapper around
private
variables. It uses
Get
/
Set
methods to retrieve and store value of a variable into it. So to be frank with you, a 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.
As a matter of fact, a Dependency Property has lots of advantages over the normal CLR properties. Let's discuss the advantages a bit before we create our own dependency property:
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.
Data Validation
: We can impose Data Validation to be triggered automatically whenever the property value is modified.
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.
Participation in Styles
: Styles are elements that define the control. We can use
Style
Setters
on Dependency property.
Participation in Templates
: Templates are elements that define the overall structure of the element. By defining Dependency property, we can use it in templates.
DataBinding
: As each of the Dependency properties itself invoke
INotifyPropertyChanged
whenever the value of the property is modified,
DataBinding
is supported internally. To read more about
INotifyPropertyChanged
,
please read
[
^
]
CallBacks
: You can have callbacks to a dependency property, so that whenever a property is changed, a callback is raised.
Resources
: A Dependency property can take a Resource. So in XAML, you can define a Resource for the definition of a Dependency property.
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.
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.
In these, some of the features are only supported by Dependency Property. Animation, Styles,
Templates
, Property value Inheritance, etc. could only be participated using Dependency property. If you use CLR property instead in such cases, the compiler will generate an error.
Now coming to the actual code, let's see how you could define a Dependency Property.
public static readonly DependencyProperty MyCustomProperty =
DependencyProperty.Register("MyCustom", typeof(string), typeof(Window1));
public string MyCustom
return this.GetValue(MyCustomProperty) as string;
this.SetValue(MyCustomProperty, value);
In the above code, I have simply defined a Dependency property. You must have been surprised why a dependency property is to be declared as static
. Yes, like you, even I was surprised when I first saw that. But later on, after reading about Dependency property, I came to know that a dependency property is 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.
After defining the most simplest Dependency property ever, let's make it a little enhanced. To Add metadata for a DependencyProperty
, we use the object of the class PropertyMetaData
. If you are inside a FrameworkElement
as I am inside a UserControl
or a Window
, you can use FrameworkMetaData
rather than PropertyMetaData
. Let's see how to code:
static FrameworkPropertyMetadata propertymetadata =
new FrameworkPropertyMetadata("Comes as Default",
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault |
FrameworkPropertyMetadataOptions.Journal,new
PropertyChangedCallback(MyCustom_PropertyChanged),
new CoerceValueCallback(MyCustom_CoerceValue),
false, UpdateSourceTrigger.PropertyChanged);
public static readonly DependencyProperty MyCustomProperty =
DependencyProperty.Register("MyCustom", typeof(string), typeof(Window1),
propertymetadata, new ValidateValueCallback(MyCustom_Validate));
private static void MyCustom_PropertyChanged(DependencyObject dobj,
DependencyPropertyChangedEventArgs e)
MessageBox.Show(string.Format(
"Property changed is fired : OldValue {0} NewValue : {1}", e.OldValue, e.NewValue));
private static object MyCustom_CoerceValue(DependencyObject dobj, object Value)
MessageBox.Show(string.Format("CoerceValue is fired : Value {0}", Value));
return Value;
private static bool MyCustom_Validate(object Value)
MessageBox.Show(string.Format("DataValidation is Fired : Value {0}", Value));
return true;
public string MyCustom
return this.GetValue(MyCustomProperty) as string;
this.SetValue(MyCustomProperty, value);
So this is a little more elaborate. We define a FrameworkMetaData
, where we have specified the DefaultValue
for the Dependency
property as "Comes as Default", so if we don't reset the value of the DependencyProperty
, the object will have this value as default. The FrameworkPropertyMetaDataOption
gives you a chance to evaluate the various metadata options for the dependency property. Let's see the various options for the enumeration.
AffectsMeasure
: Invokes AffectsMeasure
for the Layout
element where the object is placed. AffectsArrange
: Invokes AffectsArrange
for the layout element. AffectsParentMeasure
: Invokes AffectsMeasure
for the parent. AffectsParentArrange
: Invokes AffectsArrange
for the parent control. AffectsRender
: Rerenders the control when the value is modified. NotDataBindable
: Databinding
could be disabled. BindsTwoWayByDefault
: By default, databinding will be OneWay
. If you want your property to have a TwoWay
default binding, you can use this. Inherits
: It ensures that the child control to inherit value from its base.
You can use more than one option using | separation as we do for flags.
The PropertyChangedCallback
is called when the property value is changed. So it will be called after the actual value is modified already. The CoerceValue
is called before the actual value is modified. That means after the CoerceValue
is called, the value that we return from it will be assigned to the property. The validation block will be called before CoerceValue
, so this event ensures if the value passed in to the property is valid or not. Depending on the validity, you need to return true
or false
. If the value is false
, the runtime generates an error.
So in the above application after you run the code, the MessageBox
comes for the following:
ValidateCallback
: You need to put logic to validate the incoming data as Value argument. True
makes it to take the value, false
will throw the error. CoerceValue
: Can modify or change the value depending on the value passed as argument. It also receives DependencyObject
as argument. You can invoke CoerceValueCallback
using CoerceValue
method associated with DependencyProperty
. PropertyChanged
: This is the final Messagebox
that you see, which will be called after the value is fully modified. You can get the OldValue
and NewValue
from the DependencyPropertyChangedEventArgs
.
CollectionType
dependency property is when you want to hold a collection of DependencyObject
into a collection. We often require this in our project. In general, when you create a dependency object and pass the default value into it, the value will not be the default value for each instance of the object you create. Rather, it will be the initial value for the Dependency
property for the type it is registered with. Thus, if you want to create a collection of Dependency
object and want your object to have its own default value, you need to assign this value to each individual item of the dependency collection rather than defining using Metadata
definition. For instance:
public static readonly DependencyPropertyKey ObserverPropertyKey =
DependencyProperty.RegisterReadOnly("Observer", typeof(ObservableCollection<Button>),
typeof(MyCustomUC),new FrameworkPropertyMetadata(new ObservableCollection<Button>()));
public static readonly DependencyProperty ObserverProperty =
ObserverPropertyKey.DependencyProperty;
public ObservableCollection<Button> Observer
return (ObservableCollection<Button>)GetValue(ObserverProperty);
In the above code, you can see we declare a DependencyPropertyKey
using the RegisterReadonly
method. The ObservableCollection
is actually a collection of Button
which is eventually a DependencyObject
.
Now if you use this collection, you will see that when you create object of the Usercontrol
, each of them refers to the same Dependency
Property rather than having its own dependency property. As by definition, each dependencyproperty
allocates memory using its type, so if object 2 creates a new instance of DependencyProperty
, it will overwrite the Object 1 collection. Hence the object will act as a Singleton
class. To overcome with this situation, you need to reset the collection with a new instance whenever a new object of the class is created. As the property is readonly
, you need to use SetValue
to crate the new Instance using DependencyPropertyKey
.
public MyCustomUC()
InitializeComponent();
SetValue(ObserverPropertyKey, new ObservableCollection<Button>());
So for each instance, the collection will reset and hence you will see a unique collection for each UserControl
created.
DependencyProperty
supports Property
Value inheritance. By the definition, after you create a DependencyObject
for you, you can easily inherit a DependencyProperty
to all its child controls using AddOwner
method associated to the DependencyProperty
.
Each of DependencyProperty
has AddOwner
method, which creates a link to another DependencyProperty
that is already defined. Say you have a DependencyObject
A, which has a property called Width
. You want the value of the DependencyObject
B to inherit the value of A.
public class A :DependencyObject
public static readonly DependencyProperty HeightProperty =
DependencyProperty.Register("Height", typeof(int), typeof(A),
new FrameworkPropertyMetadata(0,
FrameworkPropertyMetadataOptions.Inherits));
public int Height
return (int)GetValue(HeightProperty);
SetValue(HeightProperty, value);
public B BObject { get; set; }
public class B : DependencyObject
public static readonly DependencyProperty HeightProperty;
static B()
HeightProperty = A.HeightProperty.AddOwner(typeof(B),
new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.Inherits));
public int Height
return (int)GetValue(HeightProperty);
SetValue(HeightProperty, value);
In the above code, you can see, the class B
inherits the DependencyProperty
Height
using AddOwner
without re declaring the same in the class. Thus when A
is declared, if you specify the height of A
, it will automatically be transferred to the inherited child object B
.
This is same as normal objects. When you specify the Foreground
of a Window
, it will automatically inherit to all the child elements, hence the Foreground
of each control will behave the same.
Update
Even though PropertyValueInhertence
is there for any dependency property, it will actually work for AttachedProperties
. I came to know that Property Value Inheritance only works when the property is taken as attached. If you set the Default Value for the Attached property and also set FrameworkMetaData.Inherits
, the property value will be inherited from Parent to Child automatically and also gives the chance for the Children to modify the content. Check MSDN [^] for more details. So, the example that I put above is not proper for Property Value Inheritance, but you can easily create one to see after you read the next section.
Attached property is another interesting concept. Attached property enables you to attach a property to an object that is outside the object altogether making it define value for it using that object. Seems a little confused, huh? Yes, let's see an example.
Say you have declared a DockPanel
, inside which you want your controls to appear. Now DockPanel
registers an AttachedProperty
.
public static readonly DependencyProperty DockProperty =
DependencyProperty.RegisterAttached("Dock", typeof(Dock), typeof(DockPanel),
new FrameworkPropertyMetadata(Dock.Left,
new PropertyChangedCallback(DockPanel.OnDockChanged)),
new ValidateValueCallback(DockPanel.IsValidDock));
You can see, the DockProperty
is defined inside the DockPanel
as Attached
. We use RegisterAttached
method to register attached DependencyProperty
. Thus any UIElement
children to the DockPanel
will get the Dock
property attached to it and hence it can define its value which automatically propagates to the DockPanel
.
Let's declare an Attached DependencyProperty
:
public static readonly DependencyProperty IsValuePassedProperty =
DependencyProperty.RegisterAttached("IsValuePassed", typeof(bool), typeof(Window1),
new FrameworkPropertyMetadata(new PropertyChangedCallback(IsValuePassed_Changed)));
public static void SetIsValuePassed(DependencyObject obj, bool value)
obj.SetValue(IsValuePassedProperty, value);
public static bool GetIsValuePassed(DependencyObject obj)
return (bool)obj.GetValue(IsValuePassedProperty);
Here I have declared a DependencyObject
that holds a value IsValuePassed
. The object is bound to Window1
, so you can pass a value to Window1
from any UIElement
.
So in my code, the UserControl
can pass the value of the property to the Window
.
<local:MyCustomUC x:Name="ucust" Grid.Row="0" local:Window1.IsValuePassed="true"/>
You can see above the IsValuePassed
can be set from an external UserControl
, and the same will be passed to the actual window. As you can see, I have added two static
methods to individually Set
or Get
values from the object. This would be used from the code to ensure we pass the value from code from appropriate objects. Say, you add a button and want to pass values from code, in such cases the static
method will help.
private void Button_Click(object sender, RoutedEventArgs e)
Window1.SetIsValuePassed(this, !(bool)this.GetValue(IsValuePassedProperty));
In the similar way, DockPanel
defines SetDock
method.
To conclude, DependencyProperty
is one of the most important and interesting concepts that you must know before you work with WPF. There are certain situations, where you would want to declare a DependencyProperty
. From this article, I have basically visited each section of the DependencyProperty
that you can work. I hope this one has helped you. Thank you for reading. Looking forward to getting your feedback.
Did you like his post?
Oh, lets go a bit further to know him better.
Visit his Website : www.abhisheksur.com to know more about Abhishek.
Abhishek also authored a book on .NET 4.5 Features and recommends you to read it, you will learn a lot from it.
http://bit.ly/EXPERTCookBook
Basically he is from India, who loves to explore the .NET world. He loves to code and in his leisure you always find him talking about technical stuffs.
Working as a VP product of APPSeCONNECT, an integration platform of future, he does all sort of innovation around the product.
Have any problem? Write to him in his Forum.
You can also mail him directly to abhi2434@yahoo.com
Want a Coder like him for your project?
Drop him a mail to contact@abhisheksur.com
Visit His Blog
Dotnet Tricks and Tips
Dont forget to vote or share your comments about his Writing
Retrive meta data of Static Resource from dependany property
Member 110885994-Dec-17 1:41
Member 110885994-Dec-17 1:41
I have a queation:
So i implement a Parser of WPF Contol. It pars all child contols of the control and retrive information about bindings anr references to static resources. With Bindings there is no problem, i can retrive a binding information with the class "BindingOperations". But i did't find a possibility to retrive a meta data of a static resource, i can get only a final string value of a static resource, but not a reference of a resource(resource name)
Example:
<Label Grid.Row="0" Grid.Column="0" Margin="{StaticResource MarginExtraSmall}"
VerticalAlignment="Center" Content="{x:Static p:Resources.Type}" ></Label>
So, i need to retrive for "ContentProperty" the name of the resource, in this case "Resources.Type"
can you please help me???
Thank you very much!
Leonid
Sign In·View Thread
I am so confused and overwhelmed with this article.
As I know as a teacher, make it simple.
And if you think it is simple make it more simple.
So if you can expaln this to a 6 year old, then you made it....
...so for me too komplex to follow up with all this.
Sign In·View Thread
Better than most of DP articles but still too confusing with awful example
nzmike17-Jan-16 18:55
nzmike17-Jan-16 18:55
I agree in many ways with the two comments below - and the sample code is awful, just a jumble of stuff and really no clear explanation of *why* you'd use it the way you have. This is the problem with all the articles I see - I want to see and hear about REAL WORLD situations where you'd be forced to use DPs (or it would make most sense), not just some sample app that does nothing but confuse with too many examples jumbled in together.
I have used WPF professionally since it came out without ever using an explicit hand-coded DP (I use styles and setters etc in the XAML) and have written countless great apps so I'd prefer to keep ignoring it (perhaps I'm just stuck in my ways) but I'm starting a new job and they want "deep" understanding of DPs but I am struggling to find any really useful scenarios or sample apps where it's used because it's *actually needed*, not to just to illustrate the syntax.
Thanks for your efforts anyway - it was still well worth reading but I have a very long way to go to become a guru with this stuff so my search for enlightenment will continue I guess.
Sign In·View Thread
Absolutely useless article. Makes the same basic error that so many articles of this type make: It assumes the reader already knows all about the topic so they will know, for example, what the "using" clauses will be (no mention here). No description of what each of the parameters in the DP declaration are, or mean, just an example that perhaps works somewhere, sometime..... No real meaningful description of HOW it works, just example of WHAT to do, again, an example from somewhere that works sometime. For a beginner in DP, this article confuses more than it illuminates, and shouldn't be thought of as a way to learn, eg a "tutorial"......
Sign In·View Thread
The article dives into WPF DP details without elaborating them properly. Without reading other articles and/or books about Dependency Property, it would be quite a challenge for someone new to WPF to understand fully what this article talks about. I would recommend the readers of this article to go and read at least the related section in the book "WPF Unleashed". It gives you a much better and clearer step by step definition of what DP is.
Sign In·View Thread
static Sizing()
DefaultStyleKeyProperty.OverrideMetadata(typeof(Sizing), new FrameworkPropertyMetadata(typeof(Sizing)));
public static readonly DependencyProperty FontSize1Property = DependencyProperty.Register(
"FontSize1", typeof (double), typeof (Sizing),new PropertyMetadata(new PropertyChangedCallback(Target)));
private static void Target(DependencyObject d, DependencyPropertyChangedEventArgs e)
if (e.NewValue.Equals(true))
((Sizing) d).TextBox1.FontSize = (double) e.NewValue; //eXCEPTION oBJECT REFERENCE NULL WHEN I ALCOATE THE MEMORY TO TEXTBOX THEN NEW OBJ CREATED IT CANNOT MODIFY THE FONT SIZE OF OLD OBJ.
((Sizing) d).T1.FontSize = (double) e.NewValue;
public override void OnApplyTemplate()
base.OnApplyTemplate();
this.T1 = this.EnforcePart<TextBlock>("T1");
this.TextBox1 = this.EnforcePart<TextBox>("TextBox1");
private T EnforcePart<T>(string g1)
where T : FrameworkElement, new()
T element = Template.FindName(g1, this) as T;
if (element == null)
element = new T();
return element;
public double FontSize1
get { return (double) GetValue(FontSize1Property); }
SetValue(FontSize1Property, value);
In a main window CLR property
public double FontSize1
get { return fontsize; }
fontsize = value;
OnPropertyChanged("FontSize1");
In xaml <local:Sizing FontSize1="{Binding FontSize1}"/>
IN gENERIC.XAML- <TextBox Name="TextBox1" Width="200" Height="40" FontSize="{TemplateBinding FontSize1}">
www.WHAK.com
www.ScriptCompress.com
Sign In·View Thread
This is really a great article which explains in and out of dependency object. But if you want to know in short and quick about dependency object, then take a look at this article
What is dependency object and where should I use it
Sign In·View Thread
PropertyValueInhertence => PropertyValueInheritance
location: Update in section PropertyValue Inheritance
Even though PropertyValueInhertence is there for any dependency property, it will actually work for AttachedProperties.
WPF Tutorial - Dependency Property[^]
great article
Sign In·View Thread
Great and as clear as it can be explanation for this unclear and confusing concept that even MSDN have a hard time explaining.
Sign In·View Thread
get { return (bool)GetValue(HasConnectionProperty); }
set { SetValue(HasConnectionProperty, value); }
public static readonly DependencyProperty HasConnectionProperty =
DependencyProperty.Register(
"HasConnection",
typeof(bool),
typeof(NetworkNode),
new FrameworkPropertyMetadata(
false,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
new PropertyChangedCallback(HasConnectionChangedCallBack)));
private static void HasConnectionChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
NetworkNode nn = (NetworkNode)d;
Ellipse el = nn.GetTemplateChild("PART_inner") as Ellipse;
if (el.PART_inner.Visibility == ...) <<-- exception el is null
This code works fine, except if I change the HasConnection property in visual studio properties panel, or in xaml I set HasConnection = "True", and I run the program throws an excetion: Object reference not set to an instance of an object.
Sign In·View Thread
Great article!! In brief you explain most of Dependency property concept probably most concept in book.
Sign In·View Thread
Doesn't this ignore the inheritance tree? How exactly does the parent/child relationship work from class A to class B if they are DepenencyObjects and not FrameworkElements or FrameworkContentElements?
Sign In·View Thread
There is to much chaos in this article. Sample code is also very chaotic. It's very hard to understand what author meant
Sign In·View Thread
I find some of this article's sentences hard to understand. I had to read them multiple times. So that's why I only give a vote of 4. Otherwise a nice overview over dependency properties.
Oh, and though I'm not a native speaker, I think you cannot inherit to something (just inherit from something).
Sign In·View Thread
You are correct. You cannot inherit to something.... you inherit from something. You have good English. I would not have know that you are not a native speaker if you had not said so.
Sign In·View Thread
Abhishek,
Outstanding as usual. I do have a qtn/clarification though. Will you add clarification to how setting a new value to the Dependency-Property-collection works, as in the following statement:
SetValue(ObserverPropertyKey, new ObservableCollection());
My missunderstanding stem from the fact that the ObserverPropertyKey is a static readonly value and it is being reset at every collection item constructor. It seems to be illegal?!
Many thanks,
Avi
modified 23-Oct-11 9:05am.
Sign In·View Thread
Web03
2.8:2023-08-14:1