Understanding how DependencyProperty works and is implemented - c#

The Silverlight/WPF DependencyProperty enables data binding and indicates when the property has changed in value, without implementing INotifyPropertyChanged. My question is on how does this work at the low level - how does DependencyProperty or DependencyObject perform this change notification when neither DependencyObject, DependencyProperty, nor DispatcherObject define any events. Would this have something to do with the DispatcherObject.Dispatcher property?
Dependency properties, or the DependencyObject class, do not natively
support INotifyPropertyChanged for purposes of producing notifications
of changes in DependencyObject source property value for data binding
operations.
This excellent clarification was taken word-for-word from:
http://msdn.microsoft.com/en-us/library/ms752914.aspx
http://msdn.microsoft.com/en-us/library/ms753358.aspx

Dependency properties are tightly integrated with the binding system internally. So instead of "notifying that the property changed", the code that sets the dependency property can call directly into the binding system and tell it to updated.
Similarly, things like inherited/attached properties can be updated on any descendant elements and/or the layout/measure/arrange can be updated. It can even tell any triggers (in Styles or ControlTemplates) to be reevaluated.
The Dispatcher isn't really related, but may be used during the process.
So in short, it's baked into WPF/Silverlight.

Well, when you register a DependencyProperty you provide a callback to be called when the value changes.
Here you have more details. I don't think anything else is public about the internals of WPF. I might be wrong.

Related

Automatically bind event to a Dependency Properties Value

I am trying to set up a custom user control derived from the ToggleButton control.
I would like to set up two new commands, CheckedCommand and UncheckedCommand.
I have defined the commands as below, and am able to bind to them. And I am firing them via some internal events. It all works great.
However I would like to be able to have these commands disable the button as the usual command interface does with CanExecute. As I understand it I need to use the CanExecuteChanged event and set the IsEnabled Property in here. However when am I supposed to bind this event, I looked at using the PropertyChangedCallback event of the DependancyProperty but then how do I unsubscribe the from any previously bound command.
It all ends up looking a bit convoluted, am I missing something simple or is this just the way it is.
[Description("Checked Command"), Category("Common Properties")]
public ICommand CheckedCommand
{
get { return (ICommand)this.GetValue(CheckedCommandProperty); }
set { this.SetValue(CheckedCommandProperty, value); }
}
public static readonly DependencyProperty CheckedCommandProperty = DependencyProperty.Register(
"CheckedCommand", typeof(ICommand), typeof(ToggleTextButton));
I may not understand your specific requirements but in general I wouldn't do it like this. WPF has been primarily designed to be data-driven, whereas here you're implementing event-driven notification. Events are the old-school WinForms way of doing things and they were added mainly to facilitate an easier transition from WinForms to the new data-bound architecture.
IMO a more "correct" solution here would be to expose a boolean dependency property i.e. basically the same thing as the "Checked" property in checkbox. Users of your control can then bind that one property to a boolean property in their view models whose setter will be called whenever the state changes. A second "Enabled" DP will allow both you and your user to control whether or not the control should be enabled, again similar to how it's implemented in Checkbox.
To ask an obvious question though if it's checkbox functionality you're after then why aren't you just templating checkbox? Do you really need a usercontrol for what it is you're trying to achieve?

Property change notification when property members change

Say I have a property named Location of type Point in my ViewModel, to which my View binds. I'm using MVVM Light's ObservableObject and RaisePropertyChanged setup to raise property change notifications. The problem is that when I execute the following in the ViewModel:
this.Location = new Point(100,100);
my View updates correctly. But if I do:
this.Location.Offset(10,10);
my View doesn't update, means the Location property does not notify the View about the change. Why is this so? How do sub-properties of built-in types such as Point or Size deal with change notification?
The fundamental problem is that Point is mutable.
You could write your own ImmutablePoint that allows conversion to and from the existing Point class for API compatibility, but doesn't allow methods like Offset.
It's not an ideal solution, but it gets around the problem of changing the fields on a property rather than the property itself.
In MVVM land, your ViewModel is responsible for notifying the View when properties change. The majority of the .NET classes do not implement INotifyPropertyChanged themselves, so you won't get automatic wiring when using them. You'll have to raise PropertyChanged yourself on the Location property each time you modify any properties of Location
Alternatively, you could implement your own Point object that implements INotifyPropertyChanged.
You can add INotifyPropertyChanged to your class members automatically using either Castle Dynamic Proxy (which wraps your models in a proxy at runtime) or PropertyChanged.Fody (which modifies the model's IL at compile time). Google is your friend.

When should I use dependency properties in WPF?

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.

Any way to get event, when some WPF data binding update occurs?

Any way to get event, when some WPF data binding update occurs?
UPD I'm developing a custom control extending one of standard controls. I need to get notification, when DataContext property of the ancestor control changes, or data binding causes update of any property of the ancestor control.
It sounds like you require: INotifyPropertyChanged to be implemented on your View Model. This obviously depends on your implementation but this is assuming you've followed MVVM.
This then allows you to carry out some work based on the value of a bound property changing (and an event being raised).
As others already mentioned, if your object
implements INotifyPropertyChanged and
the property supports it, register to PropertyChanged and you will be informed about changes.
If you are in a DependencyObject and add your own DependencyProperty, register a DependencyPropertyChangedEventHandler in the metadata to be informed when the property changes-
If you have a DependencyObject and
the property is a DependencyProperty, you can override
OnPropertyChanged. It will be called
every time, a DependencyProperty
value has been changed. You can then filter out the property-changes you are interested in.
If you are outside of a
DependencyObject and want to
listen to a changed value of a DepenendencyProperty, you can use
the DependencyPropertyDescriptor to register for value changes. However take care, using this may produce memory-leaks.
If you're talking about getting a notification from a control perspective (i.e. when a dependency property has been bound to) you can provide a method that will be called passing the value:
public DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
"ItemsSource",
typeof(IList),
typeof(CustomGridControl),
new FrameworkPropertyMetadata(null, OnItemsSourceChanged));
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
e.NewValue;
}

Adorning a non-DependencyObject with a DependencyProperty

I'm trying to bind to a WinForms control's DataSource property in my WPF application but I'm not having much luck...
Falafel.com gives it a shot, but although it claimes that a DependencyObject is not required to perform the binding, that seems to be the only way of doing it.
Has anyone done this before?
A. For objects not derived from DependencyObject, you don't have access to SetBinding() or ClearBinding() methods. Instead you may call the static methods BindingOperations.SetBinding() and BindingOperations.ClearBinding().
This is to actually bind a source and a target, and it can be done from any object using the static methods.
B. Now about the source and target involved in the binding, there are constraints that you can read here and that summarize to:
"The target of the binding can be any accessible property or element that is derived from DependencyProperty—an example is a TextBox control's Text property. The source of the binding can be any public property, including properties of other controls, common language runtime (CLR) objects, XAML elements, ADO.NET DataSets, XML Fragments, and so forth."
In turn DependencyProperty can exist (if I'm not wrong) only in a DependencyObject. So the target needs to live in a DependencyObject, but not the source, and not the object from where the binding is created.
And this is not exactly true, you can also use a target that is not a DO, look at the code in this page.
Also remember that you can perform a
reverse binding using
OneWayToSource type of binding. In
this case the target has not to be a
DependencyObject.

Categories