DependencyProperty and DataBinding? - wpf

In WPF:
Can someone please explain the relationship between DependencyProperty and Databinding?
I have a property in my code behind I want to be the source of my databinding.
When does a DependencyProperty (or does it) come into play if I want to bind this object to textboxes on the XAML.

The target in a binding must always be a DependencyProperty, but any property (even plain properties) can be the source.
The problem with plain properties is that the binding will only pick up the value once and it won't change after that because change notification is missing from the plain source property.
To provide that change notification without making it a DependencyProperty, one can:
Implement INotifyPropertyChanged on the class defining the property.
Create a PropertyNameChanged event. (Backward compatibility.)
WPF will work better with the first choice.

What is the DependencyProperty?
The DependencyProperty class is one of the most important design bases hidden deep in the .Net Framework WPF.
This class is protected by sealed from the .NET Framework.
This property differs from the one-dimensional general property in that it not only stores field values, but also takes advantage of the various functions provided within the class.
Most importantly, there is a full foundation for data binding. You can also send notifications whenever you bind something.
DependencyProperty
Wpf Xaml Binding
It's already a late answer, but I'll introduce the results of my research.

Related

How to apply FrameworkPropertyMetadata.AffectsArrange to a DependencyProperty

In a custom control I have a class which derives from DependencyObject and has a dependency property called MaxIdealWidth. I have several custom controls which do some pretty weird measure/arrange, and they all use this property in some way, but not in a binding.
My problem is, when everything is drawn the first time, it works well. However when the MaxIdealWidth is changed by one custom control, none of the others will do measure/arrange. I can understand why this happens, but I need to force all custom controls to measure/arrange at the same time.
FrameworkPropertyMetadata.AffectsArrange
Looking at the documentation, this looks like a promising way forward, however I have absolutely no idea how to apply it in practice. It doesn't seem to be documented from a point of view of how to use it in my situation. Can someone tell me how to apply AffectsArrange from XAML or code-behind to indicate from a custom control that a dependency property on the DataContext should cause measure/arrange?
You do that by using the FrameworkPropertyMetadata class instead of the PropertyMetadata for the last Parameter of the dependency propery Registration. There you set all the bits you like:
public static readonly DependencyProperty ArrowEndsProperty =
DependencyProperty.Register("your name",
typeof(<class>), typeof(<owner class>),
new FrameworkPropertyMetadata(<initial value>,
FrameworkPropertyMetadataOptions.AffectsMeasure));

Changing exisiting standard property to DependencyProperty

Is that possible to change for example MediaElement.Position property to DependencyProperty by inheriting MediaElement class and then creating DependencyProperty in a new class from inherited class?
How to do it? AFAIK DependencyProperty stops normal behaviour of default accessor, how to reconnect things to not break up after change?
I want to update Slider.Value through Binding thus I need MediaElement.Position as DependencyProperty. I know I can do it with DispatcherTimer but I think it's not professional solution.
You can create either a custom control (a XAML-less control that inherits from MediaElement) or a UserControl with a MediaElement somewhere in its visual tree.
In either case, create your DependencyProperty, and use the PropertyChangedCallBack (in FrameworkPropertyMetadata) to respond to changes made, and use events to listen the other way.
In either case, you are creating a new control to use instead of the MediaElement. The advantage of a User Control is that you only expose the properties needed. The disadvantage being naturally that you have to expose them all. The custom control will also expose the Position property even though you don't want to use it.

WPF+MVVM: How to use plain old ViewModelBase when DependencyProperty is needed

I am using a 3rd party WPF control whose MVVM support relies on dependency properties on the VM it is bound to. The sample that comes with the control uses a ViewModelBase class derived from DependencyObject so all is well.
My ViewModelBase implements INotifyPropertyChanged and for various reasons it is unrealistic to change it to DependencyObject.
My question is how do I use my ViewModels with this WPF control? I guess what I need is something like "embedding a dependencyobject" or "plugging dependency properties" in a plain old ViewModel.
By the way my MVVM application is interface based, i.e. everywhere SomeViewModel is ISomeViewModel.
In general, a properly designed control shouldn't require binding to a DependencyProperty, as a DP can bind to any property without issue. As such, I'd revisit whether this is truly a bug in the control implementation first, and correct that.
However, if you must do this, realize you're going to violate MVVM - using DependencyObject within a ViewModel is, by its very nature, injecting view specific framework elements into the VM. Once you decide you're okay with doing this, you can always have your ViewModel expose a DependencyObject as a property, and bind to a DependencyProperty defined on that DependencyObject instead of directly to your VM's property.

Delayed "rendering" of WPF/Silverlight Dependency Properties?

Is there a way to know the first time a Dependency Property is accessed through XAML binding so I can actually "render" the value of the property when needed?
I have an object (class derived from Control) that has several PointCollection Dependency Properties that may contain 100's or 1000's of points. Each property may arrange the points differently for use in different types shapes (Polyline, Polygon, etc - its more complicated then this, but you get the idea). Via a Template different XAML objects use TemplateBinding to access these properties. Since my object uses a Template I never know what XAML shapes may be in use for my object - so I never know what Properties they may or may not bind to. I'd like to only fill-in these PointCollections when they are actually needed.
Normally in .NET I'd but some logic in the Property's getter, but these are bypassed by XAML data binding.
I need a WPF AND Silverlight compatible solution.
I'd love a solution that avoids any additional complexities for the users of my object.
Update
One way that I've found to do this is using Value Converters. In my situation I had multiple point collections. There was a main dep. property that contained the usual shape of the data. Two alternate shapes were needed for reuse in other areas/contexts.
At first I had 3 dep. props. But, I could have just had one property (the usual shape) and used a value converted to transform the points into my other 2 desired shapes. Doing this I only make the one set of points in the control. The expense of transforming points to the secondary shapes is only incurred when used. Now my main control doesn't need to anticipate how data needs to look for every possible template thrown at the control - now its the template designers problem.
Update 2
Certainly INotifyPropertyChanged and regular properties are the recommended way to handle this.
You don't necessarily have to use dependency properties to enable data-binding. However, you then have to implement INotifyPropertyChanged if changes at the source should be propagated to the target of the binding. A "normal" .NET property is easy to lazy load perhaps like this:
PointCollection points
public PointCollection Points {
get {
return this.points ?? (this.points = CreatePoints());
}
}
PointCollection CreatePoints() {
// ...
}
I'm not sure how you can fit INotifyPropertyChanged into your control, but it sounds a bit strange that your control supplies data to other parts of the system. Perhaps you need to create a view-model containing the data that you then can let your control data-bind to.
If I paraphrase your question to
How do I get notified when dependency property is changed?
will this be correct? I draw this from your phrase "Normally in .NET I'd but some logic in the Property's getter, but these are bypassed by XAML data binding".
If I'm correct, then you can register your own property changed callback. It's always called. Doesn't matter who caused the change binding, style or trigger. The following code snippet is taken from MSDN Article "Dependency Property Callbacks and Validation":
public static readonly DependencyProperty CurrentReadingProperty =
DependencyProperty.Register(
"CurrentReading",
typeof(double),
typeof(Gauge),
new FrameworkPropertyMetadata(
Double.NaN,
FrameworkPropertyMetadataOptions.AffectsMeasure,
new PropertyChangedCallback(OnCurrentReadingChanged),
new CoerceValueCallback(CoerceCurrentReading)
),
new ValidateValueCallback(IsValidReading)
);
public double CurrentReading
{
get { return (double)GetValue(CurrentReadingProperty); }
set { SetValue(CurrentReadingProperty, value); }
}
Your takeaway here is OnCurrentReadingChanged() method. Hope this helps :).

INotifyPropertyChanged vs. DependencyProperty in ViewModel

When implementing the ViewModel in a Model-View-ViewModel architecture WPF application there seem to be two major choices how to make it databindable. I have seen implementations that use DependencyProperty for properties the View is going to bind against and I have seen the ViewModel implementing INotifyPropertyChanged instead.
My question is when should I prefer one over the other? Are there any performance differences? Is it really a good idea to give the ViewModel dependencies to WPF? What else do I need to consider when make the design decision?
Kent wrote an interesting blog about this topic: View Models: POCOs versus DependencyObjects.
Short summary:
DependencyObjects are not marked as
serializable
The DependencyObject class overrides and seals the Equals() and
GetHashCode() methods
A DependencyObject has thread affinity – it can only be accessed
on the thread on which it was
created
I prefer the POCO approach. A base class for PresentationModel (aka ViewModel) which implements INotifyPropertyChanged interface can be found here: http://compositeextensions.codeplex.com
According to the WPF performance guide, DependencyObjects definitely perform better than POCOs that implement INotifyPropertyChanged:
http://msdn.microsoft.com/en-us/library/bb613546.aspx
The choice is totally based on your business logic and UI abstraction level. If you dont want a good separation then DP will work for you.
DependencyProperties will be applicable mainly at the VisualElements level so it won't be good idea if we create lot of DPs for each of our business requirements. Also there is a greater cost for DP than a INotifyPropertyChanged. When you design a WPF/Silverlight try to design UI and ViewModel totally separate so that at any point of time we can change the Layout and UI controls (Based on theme and Styles)
Refer this post also - https://stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel . The link has a lot of reference to Model-View-ViewModel pattern, which is very relevant to this discussion.
From an expressiveness standpoint, I thoroughly enjoy using dependency properties and cringe at the thought of INotifyPropertyChanged. Apart from the string property names and possible memory leaks due to event subscription, INotifyPropertyChanged is a much more explicit mechanism.
Dependency properties imply "when this, do that" using easily-understood static metadata. It is a declarative approach that gets my vote for elegance.
Dependency properties are intended to supports binding (as a target) on UI elements not as a source to data binding, this is where INotifyProperty comes in. From a pure point of view you shouldn't use DP on a ViewModels.
"In order to be the source of a binding, a property does not need to be a dependency property; you can use any CLR property as a binding source. However, in order to be the target of a binding, the property must be a dependency property. For a one-way or two-way binding to be effective, the source property must support change notifications that propagate to the binding system and thus the target. For custom CLR binding sources, this means that the property must support INotifyPropertyChanged. Collections should support INotifyCollectionChanged."
All dependency objects cannot be serialised (This could hamper the use of ViewModels and DTO (POCO)'s.
There are differences between DP within Silverlight compared to WPF.
http://msdn.microsoft.com/en-us/library/cc221408(v=VS.95).aspx
http://msdn.microsoft.com/en-us/library/cc903933(VS.95).aspx
INotifyPropertyChanged when used also gives you the ability to add more logic in the code of your getters and setter of your properties.
DependencyProperty example:
public static DependencyProperty NameProperty = DependencyProperty.Register( "Name", typeof( String), typeof( Customer ) );
public String Name
{
set { SetValue( NameProperty, value ); }
get { return ( String ) GetValue( NameProperty ); }
}
In your getter and setter --- all you can do is simply call SetValue and GetValue respectively, b/c in other parts of the framework the getter/setter is not called, instead it directly calls SetValue, GetValue, so your property logic wouldnt reliably be executed.
With INotifyPropertyChanged, define an event:
public event PropertyChangedEventHandler PropertyChanged;
And then simply have any logic anywhere in your code, then call:
// ...
// Something cool...
// ...
if( this.PropertyChanged != null )
{
PropertyChanged( this, new PropertyChangedEventArgs( "Name" ) );
}
// More cool stuff that will reliably happen...
This could be in a getter/setter, or anywhere else.
Is it really a good idea to give the ViewModel dependencies to WPF?
.NET 4.0 will have System.Xaml.dll, so you won't have to take a dependency on an arbitrary framework to utilize it. See Rob Relyea's post about his PDC session.
My take
XAML is a language for describing objects, and WPF is a framework whose described objects are UI elements.
Their relationship is similar to C#, a language for describing logic, and .NET, a framework which implements particular kinds of logic.
XAML's purpose is declarative object graphs. The W*F technologies are great candidates for this paradigm, but XAML exists independently of them.
XAML and the entire dependency system were implemented as separate stacks for WF and WPF, probably to leverage the experience of different teams without creating a dependency (no pun intended) between them.
I too had to consider this decision recently.
I found that the INotifyPropertyChanged mechanism suited my needs better because it allowed me to glue my GUI to an existing business logic framework without duplicating state. The framework I was using had its own observer pattern and it was easy to forward one level of notification on to the next. I simply had a class which implemented the observer interface from my business logic framework and the INotifyPropertyChanged interface.
With DP you cannot define the backend that stores the state yourself. I would have had to let .net cache a copy of every item of state I was binding to. This seemed like an unnecessary overhead - my state is large and complicated.
So here I found INotifyPropertyChanged better for exposing properties from business logic to GUI.
That being said where I needed a custom GUI widget to expose a property and for changes to that property to affect other GUI widgets DP proved the simple solution.
So there I found DP useful for GUI to GUI notification.
Dependency properties are the glue of custom control creation. If you are interested in using Intelli-sense to show your properties in the properties window at XAML design time you must use Dependency properties. INPC will never show a property in the property window at design time.
It seems that Dependency Properties should be used in controls that you create such as Buttons. To use properties in XAML and use all the WPF features, those properties must Dependency Properties.
However, your ViewModel is better off using INotifyPropertyChanged. Using INotifyPropertyChanged will give you the ability to have getter/setter logic if you need to.
I recommend checking out Josh Smith's version of a base class for a ViewModel that already implements INotifyPropertyChanged:
http://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/
I think this is an excellent example of how to do a ViewModel.
I think DependencyProperty and INotifyPropertyChanged are used for two different things in Binding : the first for enabling a property to be a target of a binding and receive the input from another property (use {Binding ...} to set the property), the last when you want the value of a property to be used as the source of a binding (name in the Binding Path Expression).
So the choice is merely technical.
I prefer a more direct approach, which I blogged about in Presentation Model Without INotifyPropertyChanged. Using an alternative to data binding, you can bind directly to CLR properties without any bookkeeping code. You just write plain-old .NET code in your View Model, and it gets updated when your Data Model changes.
There is only one thing why to prefer a DependencyObject - Binding will work better. Just try an example with a ListBox and TextBox, populate list with data from INotifyPropertyChanged property vs. DependencyProperty and edit current item from TextBox...
If you want to expose properties to other controls you must use Dependency properties... But good luck because they take a while to figure out...

Resources