In MVVM should the ViewModel or Model implement INotifyPropertyChanged?

C#MvvmInotifypropertychanged

C# Problem Overview


Most MVVM examples I have worked through have had the Model implement INotifyPropertyChanged, but in Josh Smith's CommandSink example the ViewModel implements INotifyPropertyChanged.

I'm still cognitively putting together the MVVM concepts, so I don't know if:

  • You have to put the INotifyPropertyChanged in the ViewModel to get CommandSink to work
  • This is just an aberration of the norm and it doesn't really matter
  • You should always have the Model implement INotifyPropertyChanged and this is just a mistake which would be corrected if this were developed from a code example to an application

What have been others' experiences on MVVM projects you have worked on?

C# Solutions


Solution 1 - C#

I strongly disagree with the concept that the Model should not implement the INotifyPropertyChanged. This interface is not UI specific! It simply informs of a change. Indeed, WPF heavily uses this to identify changes, but that doesn't mean it is an UI interface. I would compare it to the following comment: "A tire is a car accessory". Sure it is, but bikes, buses, etc. also use it. In summary, do not take that interface as an UI thing.

Having said that, it doesn't necessarily mean I believe that the Model should be providing notifications. In fact, as a rule of thumb, the model should not implement this interface, unless it is necessary. In most cases where no server data is pushed to the client app, the model can be stale. But if listening to financial market data, then I do not see why the model cannot implement the interface. As an example, what if I have non-UI logic such as a service that when it receives a Bid or Ask price for a given value it issues an alert (ex. through an email) or places an order? This could be a possible clean solution.

However, there are different ways of achieving things, but I would always argue in favor of simplicity and avoid redundancy.

What is better? Defining events on a collection or property changes on the view model and propagating it to the model or having the view intrinsically update the model (through the view model)?

The bottom line whenever you see someone claiming that "you can't do this or that" it is a sign they do not know what they are talking about.

It really depends on your case and in fact MVVM is a framework with lots of issues and I am yet to see a common implementation of MVVM across the board.

I wish I had more time to explain the many flavors of MVVM and some solutions to common problems - mostly provided by other developers, but I guess I will have to do it another time.

Solution 2 - C#

I'd say quite the opposite, I always put my INotifyPropertyChanged on my ViewModel - you really don't want to be polluting your model with a fairly WPF specific feature like INotifyPropertyChanged, that stuff should sit in the ViewModel.

I'm sure others would disagree, but that's the way I work.

Solution 3 - C#

In M-V-VM the ViewModel always (Model not always) implements INotifyPropertyChanged

Check out the M-V-VM Project Template/Toolkit from http://blogs.msdn.com/llobo/archive/2009/05/01/download-m-v-vm-project-template-toolkit.aspx. It uses the DelegateCommand for commanding and it should be a great starting template for you M-V-VM projects.

Solution 4 - C#

I think MVVM is very poorly named and calling the ViewModel a ViewModel causes many to miss an important feature of a well-designed architecture, which is a DataController that controls the data no matter who is trying to touch it.

If you think of the View-Model as more of a DataController and implement an architecture where your DataController is the only item that touches the data, then you would never touch the data directly, but always use the DataController. The DataController is useful to the UI but not necessarily only for the UI. It is for business layer, UI layer, etc...

DataModel -------- DataController ------ View
                  /
Business --------/

You end up with a model like this. Even the business should only touch the data using the ViewModel. Then your conundrum just goes away.

Solution 5 - C#

It depends on how you've implemented your model. My company uses business objects similar to Lhotka's CSLA objects and make extensive use of INotifyPropertyChanged throughout the business model.

Our validation engine relies heavily on being notified that properties change through this mechanism and it works very well. Obviously, if you are using a different implementation other than business objects where notification of changes isn't as critical to the operation, you may have other methods for detecting change in your business model.

We also have View Models that propagate the changes from the Model where needed, but the View Models themselves are listening to the underlying Model changes.

Solution 6 - C#

I agree with Paulo's answer, implementing INotifyPropertyChanged in Models is totally acceptable and is even suggested by Microsoft -

> Typically, the model implements the facilities that make it easy to > bind to the view. This usually means it supports property and > collection changed notification through the INotifyPropertyChanged and > INotifyCollectionChanged interfaces. Models classes that represent > collections of objects typically derive from the > ObservableCollection<T> class, which provides an implementation of the > INotifyCollectionChanged interface.

Although its up to you to decide whether you want that type of implementation or not, but remember -

> What if your model classes do not implement the required interfaces? > Sometimes you will need to work with model objects that do not > implement the INotifyPropertyChanged, INotifyCollectionChanged, > IDataErrorInfo, or INotifyDataErrorInfo interfaces. In those cases, > the view model may need to wrap the model objects and expose the > required properties to the view. The values for these properties will > be provided directly by the model objects. The view model will > implement the required interfaces for the properties it exposes so > that the view can easily data bind to them.

Taken from - http://msdn.microsoft.com/en-us/library/gg405484(PandP.40).aspx

I have worked in some projects where we haven't implemented INotifyPropertyChanged in our models and due to this we faced a lot of issues; unnecessary duplication of properties was needed in VM and at the same time we had to update the underlying object(with updated values) before passing them to BL/DL.

You will face problems specially if you need to work with collection of your model objects(say in an editable grid or list) or complex models; model objects won't be updated automatically and you will have to manage all that in your VM.

Solution 7 - C#

I think that it all depends on the use case.

When you have a simple model with loads of properties, you can have it implementing INPC. By simple I mean that this model looks rather like a POCO.

If your model is more complex and lives in an interactive model domain - models referencing models, subscribing to other models' events - having model events implemented as INPC is a nightmare.

Put yourself in a position of some model entity that has to colaborate with some other models. You have various events to subscribe to. All of them are implemented as INPC. Imagine those event handlers you have. One enormous cascade of if-clauses and/or switch clausses.

Another issue with INPC. You should design your apps to rely on abstraction, not implementation. This is typically done using interfaces.

Let's have a look at 2 different implementations of the same abstraction:

public class ConnectionStateChangedEventArgs : EventArgs
{
	public bool IsConnected {get;set;}
}

interface IConnectionManagerINPC : INotifyPropertyChanged
{
	string Name {get;}
	int ConnectionsLimit {get;}
	/*
	
	A few more properties
	
	*/
	bool IsConnected {get;}
}

interface IConnectionManager
{
	string Name {get;}
	int ConnectionsLimit {get;}
	/*
	
	A few more properties
	
	*/
	event EventHandler<ConnectionStateChangedEventArgs> ConnectionStateChanged;
	bool IsConnected {get;}
}

Now look at both of them. What does IConnectionManagerINPC tell you? That some of its properties may change. You don't know which of them. In fact the design is that only IsConnected changes, as the rest of them are read-only.

On the opposite, IConnectionManager's intentions are clear: "I can tell you that my IsConnected property's value may changed".

Solution 8 - C#

I'd say in your ViewModel. It's not part of the Model as the Model is UI agnostic. The Model should be 'everything EXCEPT business agnostic'

Solution 9 - C#

But sometimes (as in this presentation link text) model is service, which supplies application with some data online and then you need to emplement notification that new data arrived or data has changed using events...

Solution 10 - C#

I think the answer is quite clear if you wish to adhere to the MV-VM.

see: http://msdn.microsoft.com/en-us/library/gg405484(v=PandP.40).aspx

In the MVVM pattern, the view encapsulates the UI and any UI logic, the view model encapsulates presentation logic and state, and the model encapsulates business logic and data.

> "The view interacts with the view model through data binding, > commands, and change notification events. The view model queries, > observes, and coordinates updates to the model, converting, > validating, and aggregating data as necessary for display in the view. > "

Solution 11 - C#

Implementing INPC in models could be used if the models are plainly exposed in the ViewModel. But generally, the ViewModel wrap the models is his own classes to reduce the model complexity (which should not be usefull for the binding). In this case the INPC should be implemented in the ViewModel.

Solution 12 - C#

I am using the INotifyPropertyChange interface in a model. Actually, a model property change should be fired by the UI or external client only.

I've noticed several advantages and disadvantages:

Advantages

Notifier is in the business model

  1. As per domain driven, it is right. It should decide when to raise and when not to.

Disadvantages

The model has properties (qty, rate, commission, totalfrieght). Totalfrieght is calculated using qty, rate, commission change.

  1. On loading values from db, total frieght calculation is called 3 times (qty, rate, commission). It should be once.

  2. If rate, qty is assigned in the business layer, again notifier is called.

  3. There should be an option to disable this, possibly in the base class. However, developers could forgot to do this.

Solution 13 - C#

Just use the INotifyPropertyChange in your viewmodel and not in the Model,

the model usually uses the IDataErrorInfo to handle the validation errors so just keep in your ViewModel and you are right on your MVVM road.

Solution 14 - C#

Normally ViewModel will implement the INotifyPropertyChanged. Model can be anything(xml file, database or even object). Model is used to give the data to the viewmodel, which propagates to the view.

see here

Solution 15 - C#

Suppose that the reference of the object in your view changes. How you will notify all properties to be updated in order to show the correct values? Calling OnPropertyChanged in your view for all object's properties is rubbish to my point of view.

So what I do is to let the object itself to notify anyone when a value in a property changes, and in my view I use bindings like Object.Property1, Object.Property2 and on. In that way if I just want to change the object that is currently maintained in my view I just do OnPropertyChanged("Object").

To avoid hundreds of notifications during the loading of objects, I have a private boolean indicator that I set it to true during loading which is checked from the object's OnPropertyChanged and does nothing.

Solution 16 - C#

imho i think the viewmodel implements INotifyPropertyChange and the model could use notification on a different "level".

eg with some document service and a document object you have a documentChanged event that a viewmodel listens to to clear out and rebuild the view. In the edit viewmodel you have a propertychange for the properties of the document to support the views. If the service does a lot with the document on save (updating change date, last user and so on) you easy get a overload of Ipropertychanged events and just a documentchanged is enough.

But if you use INotifyPropertyChange in your model i think it is good practice to relay it in your viewmodel in stead of subscribing to it directly in your view. In that case when the events change in your model you only have to change the viewmodel and the view stays untouched.

Solution 17 - C#

All properties, which are binded to my view, are in my ViewModel(s). Thus they should implement the INotifyPropertyChanged interface. Therefore the View gets all changes.

[Using the MVVM Light toolkit, I let them inherite from ViewModelBase.]

The Model holds the business logic, but has nothing to do with the view. Thus there´s no need for the INotifyPropertyChanged interface.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEdward TanguayView Question on Stackoverflow
Solution 1 - C#Paulo SousaView Answer on Stackoverflow
Solution 2 - C#Steven RobbinsView Answer on Stackoverflow
Solution 3 - C#Soni AliView Answer on Stackoverflow
Solution 4 - C#RhyousView Answer on Stackoverflow
Solution 5 - C#Steve MitchamView Answer on Stackoverflow
Solution 6 - C#akjoshiView Answer on Stackoverflow
Solution 7 - C#dzendrasView Answer on Stackoverflow
Solution 8 - C#Steve DunnView Answer on Stackoverflow
Solution 9 - C#Andrey KhataevView Answer on Stackoverflow
Solution 10 - C#John DView Answer on Stackoverflow
Solution 11 - C#stéphane BoutinetView Answer on Stackoverflow
Solution 12 - C#Anand KumarView Answer on Stackoverflow
Solution 13 - C#AdamView Answer on Stackoverflow
Solution 14 - C#SyedView Answer on Stackoverflow
Solution 15 - C#Dummy01View Answer on Stackoverflow
Solution 16 - C#BramView Answer on Stackoverflow
Solution 17 - C#donotbefakeView Answer on Stackoverflow