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
Related
What would be the best way to bind an ItemsControl to an array of, say, System.Doubles, while being able to push back changes to underlying element?
Details
I'm using ItemsControl to provide user with a set of vertical guides. The underlying VM object provides the positions of these guides as a double[]. I bind this array to the ItemsSource and get my guides positioned correctly in the ItemsControl (using Transform). So far so good.
However, these guides need to be adjustable. The ItemTemplate of my ItemsControl provides a Thumb using which user can adjust the position of the guide. However, since the underlying element is an intrinsic type (a double), changes won't push back to the source obviously (or am I wrong?!)
I'm now heading in the direction of creating DoubleByRef class, i.e. which basically will be a double class with a member Value of type double (hoepfully that's clear, LOL). But just wanted to check with the community if there's something better.
When you bind ItemsSource to a collection (or an array), an item container is generated for each element in the collection. Each container's data context points to the corresponding element from the source collection, meaning any bindings within the item container use that element as its binding source. While you can certainly set a two-way binding on any value that is accessible via the binding source, you cannot set a two-way binding on the source itself. There would be no way to do this, as the binding is only aware of the element's value; it knows nothing of the collection containing the element. As it does not know where that value came from, it has no way to replace it. In fact, for a collection of value types like double[], the binding source isn't even the same value that's in the array--it's a boxed copy.
The only way to make this work like you envisioned is to wrap the guideline values in some reference-typed wrapper, like your proposed DoubleByRef. Then you will be able to set up a two-way binding to the wrapped value.
You potentially have another problem, which is that arrays do not support collection change notification. If your number of values is always fixed, this may not be a problem for you, and you can just bind to a DoubleByRef[].
However, if values can be added or removed, your values will need to be wrapped in a collection implementing INotifyCollectionChanged. An ObservableCollection<DoubleByRef> would work.
As a fun aside, WPF does include a DoubleCollection, but it doesn't actually solve the element binding problem, nor does it implement change notification. Would you care to guess what it's used for? Yep—guidelines!
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'm designing an user control and I'd like to make its behaviour configurable - but just once, when it's created. I don't need it to adapt later on, since I know beforehand that a specific window will to use it with a specific configuration.
Consider this simple markup:
<MyControl SomeProperty="True" SomeOtherProperty="12345" />
SomeProperty and SomeOtherProperty are DependencyProperties declared in my codebehind.
The issue is: The control does some preprocessing of its input data in its constructor, before InitializeComponent() is called. On that stage, I don't have the access to SomeProperty or SomeOtherProperty defined by the user - they still have the default values.
After that, if these properties are set in the XAML, they're assigned the values after the constructor. I can respond to them by introducing a PropertyChangedCallback and performing the calculations over again after each property is updated.
This is sub-optimal since I just want to pass the values once and make sure that the control's initialization logic is only ran once too - already with correct settings. The solution with PropertyChangedCallbacks requires me to make this control more complex, i.e. responsive to any changes to these dependency properties during the control's whole lifetime. This is much more than I need - it would be satisfactory for my properties to be read-only and set only once at the moment of control creation.
How can I manage to do that while keeping the XAML markup clean?
Your control must be constructed in order for WPF to set the properties - there is no way to "delay" the construction until after the properties are set.
Instead of putting your initialization logic in the constructor, you might want to try putting it elsewhere, such as subscribing to the Loaded event and initializing there. This will happen after the properties are set.
I've searched around, but don't think I really found an answer. I'm trying to get a handle more on data binding and starting to see things coming together. Can you do data binding to something like "IsEnabled" based on TWO Properties, if so, how...
ex: A Window has some controls... certain controls may or may not be enabled at certain times. Some times it's as simple as when data is available (such as finding a record to edit), or when adding... I would consider this an "Editing" mode of the window. Sometimes, certain controls are only available when doing an Edit AND the user has admin permissions.
BOTH conditions need to be true for the control to be "enabled". Similarly could be applied to visibility of a control under similar conditions.
If you're using the MVVM model (which you really should if you're doing WPF development), then you're thinking about it the wrong way.
This sort of logic belongs in the ViewModel. You should have a single property on the ViewModel that represents the visiblity of the control (or controls) and have whatever logic is required (permissions, data validity, mode, etc.) in the ViewModel to determine this value. Putting the logic on the view hamstrings you and violates SOC.
The ViewModel is supposed to model your view. That is, there should (in most cases) be a 1:1 correlation between elements and concepts in your view (such as whether or not a feature is enabled or visible) and properties on your ViewModel.
You could use MultiBindings and some custom aggregate multi-value converters to achieve this declaratively. Alternatively, it may be more explicit (and therefore recommended) to place an additional property on your view model which compounds the values of the other view model properties.
Couldn't I just use a single binding converter and as a parameter pass in the DataContext and from there pick what properties I want to use?
If you pass the whole object instead of the individual properties, then the binding expression will not be re-evaluated when the individual properties change. You will be losing the benefit of the INotifyPropertyChanged mechanism.
You might want to be more explicit and take in the minimum extra information (which is just generally good programming practice), or you may want information from more than one source - e.g. Your value might be dependent on a property of the datacontext and the checked state of a checkbox somewhere else in the view.
You can do that, but the binding will not update if the relevant properties change that way. Besides the updates Multibinding is needed for more complex bindings to different controls and data-objects.