375

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?

lokusking
  • 7,396
  • 13
  • 38
  • 57
bitbonk
  • 48,890
  • 37
  • 186
  • 278
  • 11
    see http://stackoverflow.com/questions/1329138/how-to-make-databinding-type-safe-and-support-refactoring/1333874#1333874 for a compiler checked way of implementing INotifyPropertyChanged. Avoiding having the property names as a magic string. – Ian Ringrose Aug 26 '09 at 11:57
  • 12
    Generally there is a major difference between a dependency property and a normal property in a class which implements INotifyPropertyChanged. Dependency properties could be source or target in data binding but normal properties with INotifyPropertyChanged support could be used as source only. So these solutions are not fully interchangeable. Data binding infrastructure requires a DP as the target to work, but the source may be either a normal property with INotifyPropertyChanged support or a common DP. – Mostafa Rezaei Aug 26 '11 at 19:37
  • 4
    See http://stackoverflow.com/a/10595688/200442 for the .net 4.5 way of implementing `INotifyPropertyChanged`. – Daniel Little Sep 17 '12 at 00:49
  • best explained here https://stackoverflow.com/a/3552550/366064 – Bizhan Oct 16 '17 at 11:30

14 Answers14

222

Kent wrote an interesting blog about this topic: View Models: POCOs versus DependencyObjects.

Short summary:

  1. DependencyObjects are not marked as serializable
  2. The DependencyObject class overrides and seals the Equals() and GetHashCode() methods
  3. 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

Boris Callens
  • 90,659
  • 85
  • 207
  • 305
jbe
  • 2,314
  • 1
  • 14
  • 2
  • 24
    DependencyObject also takes a dependency on the WPF libraries, whereas POCO does not, allowing your view models to drive some other UI stack where WPF isn't available (Compact Framework, Mono). – codekaizen Jan 06 '10 at 08:21
  • 29
    It's clear then, that the Dependecy Properties are solely built for the UI and not for the business layer. – Andrei Rînea May 04 '10 at 07:29
  • 11
    Dependancy Properties also require a DependencyObject parent. Your ViewModel really shouldn't inherit from DependencyObject. – Gusdor Jun 13 '11 at 10:56
42

According to the WPF performance guide, DependencyObjects definitely perform better than POCOs that implement INotifyPropertyChanged:

http://msdn.microsoft.com/en-us/library/bb613546.aspx

James Ashley
  • 539
  • 4
  • 4
  • 1
    I must agree on that one ;-) : http://blog.lexique-du-net.com/index.php?post/2010/02/24/DependencyProperties-or-INotifyPropertyChanged – Jonathan ANTOINE Apr 20 '11 at 22:02
  • If you select .NET Framework version 4, then the link still works. It's just not available for "current version". – doubleYou Mar 17 '16 at 13:33
  • Thanks for pointing this out, there's a lot of scandalous misinformation out there of devs making salacious claims that INotifyPropertyChanged is faster or incurs less overhead than DPs and it's simply unfounded. DPs are fast, elegant and powerful ways to structurally define the virtual (data) tree. – tpartee Jul 06 '17 at 01:44
  • There is a hidden evil to the DependencyObjects. They need to be created on the same thread as the controls that bind to them. That means GUI thread. That means you need to Dispatch the creation to that thread. You can't have those things loaded and created on some background thread from DB for example. Unless you dispatch the creation. Insane. – ed22 Apr 08 '19 at 06:05
29

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.

Community
  • 1
  • 1
Jobi Joy
  • 49,102
  • 20
  • 108
  • 119
  • 9
    The post by jbe answers the differences more accurately. Just because a VM (or Presenter) inherits from DependencyObject doesn't mean that it can't be styled or isn't logically separate from the View, it just means that the storage for the property values is different than explicitly declared fields in the POCO style. That being said, serialization, logical equality, and thread affinity are real issues which DepedencyObject-based VMs have to deal with. – micahtan May 25 '09 at 19:38
  • "Also there is a greater cost for DP than a INotifyPropertyChanged" - where is your source of proof on this? A lot of devs make this claim without any evidence to support it. According to MSDN it's not true. "try to design UI and ViewModel totally separate so that at any point of time we can change the Layout and UI controls" - again, this has absolutely nothing to do with POCO + PropChange versus DO/DP. If anything, the Reflection and Path registry in DO/DP improves your ability to work on the visual side. – tpartee Jul 06 '17 at 01:47
20

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.

Bryan Watts
  • 44,911
  • 16
  • 83
  • 88
19

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

Nick Hermans
  • 349
  • 2
  • 3
  • I've been using serialized Dependency Objects since 2009 without issue, so not sure what you're talking about when you say "All dependency objects cannot be serialized" - yes they can. In fact there are many options: https://www.codeproject.com/Articles/61440/Serialize-DependencyObject-It-s-easy http://www.emphess.net/2008/11/25/dependencyproperty-serialization/ And one of my personal favorites: just provide backing stores for all of your DPs and make those serializable (no good simple examples were readily available in 2 minutes of searching on Google, but I assure you this works). – tpartee Jul 06 '17 at 01:34
15

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.

Wilka
  • 28,701
  • 14
  • 75
  • 97
Adam
  • 28,537
  • 15
  • 60
  • 73
  • 12
    You can get change notifications from DependencyProperties as well. See PropertyMetadata.PropertyChangedCallback. Example at: http://msdn.microsoft.com/en-us/library/ms745795.aspx – Joe White Apr 25 '09 at 17:11
  • 2
    Also, you can call SetValue from anywhere as well, not just from inside the property – aL3891 May 05 '11 at 21:30
  • This is misleading and untrue - there are multiple ways to hook into change events on a DP, even when it's changed 'internally'. One of them was pointed out above by Joe White – tpartee Jul 06 '17 at 01:41
7

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.

Bryan Watts
  • 44,911
  • 16
  • 83
  • 88
  • By answering, you seem to be making the assumption that bitbonk considers XAML and WPF to be the same. ViewModels should have as few WPF dependancies as possible, not to increase logical separation, but to decrease code complexity and avoid all the issues associated with simply writing logic in a user control's code-behind. You will inevitably implement WPF concepts like ICommand and present behaviour that only WPF / Silverlight will be able to wrap easily - your only presentation threading concerns in a view model should be CollectionViews and ObservableCollection. – Gusdor Jun 13 '11 at 11:00
7

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.

morechilli
  • 9,827
  • 7
  • 33
  • 54
6

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.

JWP
  • 6,672
  • 3
  • 50
  • 74
4

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.

Domnik
  • 41
  • 1
  • 2
    An INotifyPropertyChanged can be used in either case. You can bind TwoWay to it. A DependencyProperty is required for technical reasons only for some actions performed on a View object (setting some properties when instantiating a View object in XAML, for instance). A DependencyProperty is never required for a ViewModel. – oillio Feb 01 '11 at 00:56
4

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.

timothymcgrath
  • 1,318
  • 1
  • 9
  • 19
3

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.

Michael L Perry
  • 7,327
  • 3
  • 35
  • 34
  • Without `INotifyPropertyChanged`, [`PropertyDescriptor`](http://msdn.microsoft.com/en-us/library/system.componentmodel.propertydescriptor.aspx) are used, which causes [memory leaks](http://support.microsoft.com/kb/938416) – Tilak Mar 15 '13 at 07:25
  • The Update Controls library that I present in that blog post uses weak references, not property descriptors. It does not leak memory. – Michael L Perry Apr 09 '14 at 14:56
  • 1
    Michael, your library generates a lot of code. I don't see benefits. I can achieve the same by generating model wrapper with generated PropertyChanged event calls. – Der_Meister Jan 01 '16 at 14:41
3

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...

akjoshi
  • 15,374
  • 13
  • 103
  • 121
ramos
  • 39
  • 1
0

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...

JWP
  • 25
  • 1