I have been reading about dependency properties in several books but all have one thing in common, they just tell us how they are implemented( using static readonly DependencyProperty etc.) but does not tell the exact way they work from inside.
I mean they are implemented as static but still applies to all objects.
Second point of confusion is attached properties.
Is there any tutorial available that can explain all these concepts in an easy way?
My mental model of how dependency properties work:
Any DependencyObject class implements two special properties. One, a static property of the class, is a dictionary of DependencyProperty objects. Every instance of the class can look inside that dictionary to find metainformation about each DependencyProperty - the property's name, its type, any callbacks that have to be called when it's get and set, how it participates in property inheritance, and so on. When you register a dependency property, you're adding an entry to this dictionary.
The other property is an instance property: it's a dictionary, keyed by DependencyProperty, that contains the local value of each DependencyProperty, if it has been set.
The SetValue and GetValue methods that you implement in the setter and getter of the CLR property are basically lazy evaluation on steroids. Instead of storing and retrieving the value of the property in a backing field, they store and retrieve the value of the property in the value dictionary.
The magic of dependency properties is in what GetValue and SetValue actually do.
GetValue looks up the value for the property in the object's value dictionary. If it doesn't find it, it calls GetValue on the parent element, to get what the parent element thinks the value is. For instance, when you create a TextBox in a Window, anything that looks at the TextBox's FontFamily is actually calling GetValue. Unless you've explicitly set the font, there's no entry in its dictionary for that property. So GetValue asks the parent element for the value. The parent element may or may not have FontFamily set; if not, its call to GetValue to returns the value from its parent. And so on, until the Window object is reached and the actual FontFamily value is found.
If you set FontFamily on the TextBox, SetValue stores the value in the value dictionary. The next time anything needs to get the value of the FontFamily for that TextBox, GetValue finds the value in the dictionary and returns it, so it doesn't need to ask the parent element.
If you set FontFamily on the Window, SetValue not only updates the value in Window's value dictionary, it fires off a property-change event that everything dependent on the property hears. (That's why they're called dependency properties, remember.) And if the thing depending on the property is itself a dependency property, it fires off its own property-change events. This is how it is that changing the FontFamily on the Window changes the font for every control in the window and also prompts WPF to re-render the controls that have changed.
Attached properties work using the same kind of approach. Any object that can have attached properties has a dictionary that the attached properties' values are stored in. When you set Grid.Column on a CheckBox in XAML, you're just adding an entry to that CheckBox's dictionary. When the Grid needs to know what column the CheckBox is in, it looks the value up from that dictionary. When you set Grid.IsSharedSizeScope to True on an object, that object's dictionary will contain a new property - a dictionary that contains widths/heights for each SharedSizeKey.
I should emphasize that this is my mental model. I haven't sat down with Reflector and looked at the actual implementation of Register, GetValue, and SetValue to figure out how they actually work. I may be wrong about the details. But it's a model that accurately predicts how this stuff behaves, so it's good enough.
The concept of storing property values in dictionaries is pretty weird to C# programmers. It's old hat to Python programmers, though. In Python, all class properties - all objects, in fact - are stored in dictionaries, and so you can get to their value either through property accessors or just by looking them up. Dependency properties and attached properties are just another way in which .NET, having stolen everything Java had that was worth stealing, is now plundering Python. (Or from wherever Python plundered them from.) Learning Python has made me a much better C# programmer; I recommend it to any C# developer who hasn't done it yet.
Here is a tutorial on dependency properties http://www.wpftutorial.net/DependencyProperties.html that explains a little bit about how they work.
The short explanation of why the DependencyProperty object is in a static field is that it represents the description of the property, not the value of the property. Each DependencyObject has a mapping from DependencyProperty objects to their values.
This is also how attached properties work. Because each DependencyObject is storing a mapping from any DependencyProperty to a value, any type can create a new DependencyProperty and set it on any existing DependencyObject.
just see this post by joshsmith it has some additional informatin in it
http://joshsmithonwpf.wordpress.com/2007/06/22/overview-of-dependency-properties-in-wpf/
You can see below a very basic example of dependency property that creates a custom control text box in which space will be not allowed means user can not type space into text box.
1) Create a class with the name of ValidatedTextBox and write the following code in this class file:
public class ValidatedTextBox : TextBox
{
public ValidatedTextBox()
{
}
public static readonly DependencyProperty IsSpaceAllowedProperty =
DependencyProperty.Register("IsSpaceAllowed", typeof(bool), typeof(ValidatedTextBox));
public bool IsSpaceAllowed
{
get { return (bool)base.GetValue(IsSpaceAllowedProperty); }
set { base.SetValue(IsSpaceAllowedProperty, value); }
}
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
base.OnPreviewKeyDown(e);
if (!IsSpaceAllowed && (e.Key == Key.Space))
{
e.Handled = true;
}
}
}
2) Now use the above control into your .XAML file
a) Add namespace of custom control text box like below:
xmlns:CustomControls="clr-namespace: ValidatedTextBox;assembly= ValidatedTextBox "
b) Now, use custom control text box like below:
<CustomControls:ValidatedTextBox IsSpaceAllowed="False" x:Name="MyTextBox" />
It will create a custom control text box that will not allow space. So, Basically Dependency property allows to add feature, extend feature of any control.
Related
We're in WinRT XAML.
I have a custom control B with a dependency property Items, the control is in a template for another control. The dependency property is initialized to an new empty collection using the PropertMetadata type. It is never data-bound - keep that in mind.
When I enter the page, the control is instantiated as part of the template for another custom control A. From a breakpoint in the constructor for B, when I check the value of Items, it contains 0 items.
As part of other activity, control A 'manually' calls B.Items.Add() to insert data. There is no data-binding.
When I navigate backward and then click to navigate to the page again, the constructor is again fired but this time Items still has the values that A added. It retains its value.
So even though the control is unloaded and loaded (I can see the events), the control and dependency property is not reinitialized.
Is this correct?
The dependency property is declared as a static field in your class B. It is initialized exactly once and hence the new collection in the property metadata is initialized only once and later shared by all "instances" of the property. This is a common mistake made in dependency property declarations.
You should set the dependency property value to a new empty collection in the constructor of class B instead of providing a default value by property metadata.
When should I use dependency properties in WPF?
They are static, so we save a lot on memory, compared to using .NET properties.
Other gains of using dependency properties over .NET properties are:
1) no need to check thread access
2) prompt a containing element to be rendered
etc...
So it seems I should ALWAYS use dependency properties in my projects where I use WPF?
Maybe for some trivial properties of helper classes here and there I could
get away with .NET properties...
Dependency Property is a broad concept to explain which might take couple of pages to write. So just to answer your main question, Dependency property is used where
You know the property is going to be the binding target i.e you are creating a user control/custom control and want property that should be binding driven.
You want automatic property change notifications (coerse and validation also).
We want value inheritance in styles,themes, parent or default value.
There is not need to create the properties on Model or ViewModel layer as dependency properties most of the time as that is not going to help much on memory saving front as most of the properties we define in model/VM will have values per instance as they will be constantly changing. Resolving Dependency property value is a burden in itself so making property dependency unnecessarily is not advisable.
Thanks
The main reason to create DependencyProperty is when you write you own WPF control.
DependencyProperties can be used as binding source and target, and can be animated.
The properties of all framework's controls are implemented as DependencyProperty, that why you can make powerful data binding in XAML.
However in most situation, like in with the MVVM pattern, you don't need dependency properties, INotifyPropertyChanged is enough.
The main difference is, that the value of a normal .NET property is read directly from a private member in your class, whereas the value of a DependencyProperty is resolved dynamically when calling the GetValue() method that is inherited from DependencyObject.
When you set a value of a dependency property it 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 of an entry is the name of the property and the value is the value you want to set.
The advantages of dependency properties are
Reduced memory footprint:
It's a huge dissipation to store a field for each property when you think that over 90% of the properties of a UI control typically stay at its initial values. Dependency properties solve these problems by only store modified properties in the instance. The default values are stored once within the dependency property.
Value inheritance:
When you access a dependency property the value is resolved by using a value resolution strategy. If no local value is set, the dependency property navigates up the logical tree until it finds a value. When you set the FontSize on the root element it applies to all textblocks below except you override the value.
Change notification:
Dependency properties have a built-in change notification mechanism. By registering a callback in the property metadata you get notified, when the value of the property has been changed. This is also used by the databinding.
check the below url for more details about the magic behid it
dependency properties in WPF
CLR Property vs. Dependency Property
A CLR property reads directly from the private member of the class. The Get() and Set() methods of the class retrieve and store the values of the property.
Whereas when you set a value of a Dependency Property it 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 of an entry is the name of the property and the value is the value you want to set.
Advantages of a Dependency Property
Less memory consumption
The Dependency Property stores the property only when it is altered or modified. Hence a huge amount of memory for fields are free.
Property value inheritance
It means that if no value is set for the property then it will return to the inheritance tree up to where it gets the value.
Change notification and Data Bindings
Whenever a property changes its value it provides notification in the Dependency Property using INotifyPropertyChange and also helps in data binding.
Participation in animation, styles and templates
A Dependency Property can animate, set styles using style setters and even provide templates for the control.
CallBacks
Whenever a property is changed you can have a callback invoked.
Resources
You can define a Resource for the definition of a Dependency Property in XAML.
Overriding Metadata
You can define certain behaviours of a Dependency Property using PropertyMetaData. Thus, overriding a metadata from a derived property will not require you to redefine or re-implement the entire property definition.
Perhaps you should take another look at the Dependency Properties Overview page at MSDN.
Personally, I would only ever create a DependencyProperty when I really need to. For the most part, I use normal CLR properties in data type and view model classes to bind to... this is absolutely fine, as long as I implement the INotifyPropertyChanged interface.
So for all of my usual data bindings, I use normal CLR properties. I only declare a Dependency Property in order to provide some added functionality in a UserControl.
Dependency properties are used when you want data binding in a UserControl, and is the standard method of data binding for the WPF Framework controls. DPs have slightly better binding performance, and everything is provided to you when inside a UserControl to implement them.
Otherwise, you typically use INotifyPropertyChanged for binding elsewhere, since it's easier to implement in stand-alone classes and has less overhead. As far as your original assumptions:
There is a local instance of your variable, you definitely do not save any overhead over a property since there is significant data binding logic built-in.
They must be accessed on the main thread.
I am not sure if this is even possible, but here is my setup:
I have a customized textbox that is only meant to deal with hotkey selection. In here I have a DependencyProperty that is for the SelectedHotKey.
Then I have a custom control that is a label, the textbox, and a button. This control also exposes a DependencyProperty of the same name as the TextBox, and it merely ties to the TextBox via:
SelectedHotKey="{Binding ElementName=Main, Path=SelectedHotKey, Mode=TwoWay}"
With this dependency property, I am looking to set the textbox's SelectedHotKey, which will change the Text appropriately.
I am then using that user control and binding to my ViewModel.
I have all of this working except for the initialization case.
When my ViewModel is already set up and passed to the UserControl in the binding, that initial setter does not even get hit, so it does not propogate down through my controls. I thought about putting in a PropertyMetaData method, however that is a static method and I do not have access to my instance textboxes.
Any ideas? Let me know if I need to clarify further.
Don't put code logic in the CLR property wrapping the dependency property. As you have already seen, there is no guarantee they will ever be called since the framework can call SetValue directly on the dependency property.
You're in the right track: you have to use the dependency property metadata. Access the instance by using the first parameter of the property changed callback.
DependencyProperty SomeProperty = DependencyProperty.Register(
"Some",
propertyType,
ownerType,
new FrameworkPropertyMetadata(defaultValue, OnSomePropertyChanged));
static void OnSomePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
// "d" is your instance here, cast it to the required type
}
We need to assign the Name property at the runtime using the data binding. We have the control template defined and WPF doesn't allow to bind the name from the the Data Bind object.
If I do, I get error like,
Error 3 MarkupExtensions are not
allowed for Uid or Name property
values, so '{Binding Name}' is not
valid. Line 15 Position
36. C:\Users\gsubramani\Workspace\ProLinkIII_Experiment\BasicFrame\Resources\TreeTemplate.xaml 15 36 BasicFrame
To work around, Is it possible to define a custom property which intern set the Name property of the control through data binding?
I don't know how to the handle the DependencyProperty in WPF so that I can define a custom property that intern set the Name property of the control? ( I am very new to WPF world).
If you need this for UI Automation, I'd recommend using the solution described here:
http://www.jonathanantoine.com/2011/11/03/coded-ui-tests-automationid-or-how-to-find-the-chose-one-control/
You can use the AutomationProperties.AutomationId with binding in WPF, and you can use this value as automationid in your UI Automation client.
You would need to define an attached dependency as per the documentation here:
http://msdn.microsoft.com/en-us/library/cc903943%28VS.95%29.aspx
Then provide a method which is invoked when this property changes. You can do this by adding another argument to the propertyMetdata, that points to a static method:
private static void OnMyNamePropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
// d is the object which the attached property has been set on
}
In this handler, d, is the object that the property has been attached to, and e.NewValue will contain the name.
However, I think it is a little odd that you want to bind the Name of your elements. Can you please share why you want to do this?
Regards, Colin E.
I'm trying to figure out what exactly Dependency Properties are, but when I look anywhere for a definition, I only find "how to use" but not "what it is".
Imagine you are asked on a job interview - what is a dependency property. What would be your answer?
A DependencyProperty is a property whose value depends (or can depend) on some other source (such as animation, data binding, styles, or visual tree inheritance). A regular property's value is stored in the object it belongs to, while you can think of a dependency property as being stored in a database somewhere. This database is essentially composed of a dictionary that maps (object, property) pairs to their values, along with a mapping of which properties depend on other properties (e.g. so when you change the DataContext of a Panel, it can notify all the children inside the panel).
So why do they store property values in some magic database somewhere? There are a few reasons:
It reduces storage space. Adding a property (even if its value is null) to a class adds 4 bytes (8 for a 64-bit process) of space to every instance of the class. A DependencyProperty only takes up space when an instance has a value. For example, a FrameworkElement has dozens of dependency properties, most of which are never assigned values. If all those properties were stored in the class, each instance would be hundreds of bytes. Instead each instance is only about 40 bytes.
It enables attached properties. Properties like Canvas.Left and Grid.Row have to be stored on objects that have never heard of a Canvas or Grid, so where do you put them? You put them in a database somewhere.
It enables automatic property changes. Imagine how you would implement something like styles or property inheritance (the ability to set something like a font or data context on a parent element and have its value propagate to all child elements). Having all of this stored in a database makes it so the code is all in one place instead of being implemented separately for each object and property that needs it.
"gives you a bunch of infrastructure to do all the things that you often want to do with a normal property - validate it, coerce it into a proper range, give out change notifications, and a number of other aspects."
WPF Tutorial - Introduction To Dependency Properties
A dependency property is a property that is backed by the WPF property system instead of by a field in the declaring class.
The significance of this is that, because WPF owns the property, WPF can factor in various considerations when calculating the property value -- such as animations, styles and data bindings. Another consequence is that because properties are managed by WPF they don't have to be declared on the classes that conceptually have the state: hence, atttached properties, which allow e.g. a Grid to associate Grid-specific state with non-Grid objects.
(By the way, I've mentioned WPF above because this is the main framework that uses DPs, but Windows Workflow Foundation also has the notion of dependency properties. So to be strictly correct a DP is a property that is backed by an external property system, specifically one which allows factors other than "the last set value" to come into play when getting the property value.)
MSDN provides a good definition, description and examples
For more deep understanding of DependencyProperty check here
A dependency property depends on multiple providers for determining its value at any point in time. These providers could be an animation continuously changing its value, a parent element whose property value propagates down to its children, and so on.
Arguably the biggest feature of a dependency property is its built-in ability to provide change notification.
Whenever the value of a dependency property changes, WPF can automatically trigger a number of actions, depending on the property’s metadata. These actions can be re-render-
ing the appropriate elements, updating the current layout, refreshing data bindings, and
much more. One of the most interesting features enabled by this built-in change notifica-
tion is property triggers, which enable you to perform your own custom actions when a
property value changes, without writing any procedural code