176

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?

akjoshi
  • 15,374
  • 13
  • 103
  • 121
Edward Tanguay
  • 189,012
  • 314
  • 712
  • 1,047
  • 4
    if you do implement INPC, give https://github.com/Fody/PropertyChanged a try - it will save you weeks of typing. – CAD bloke Apr 26 '16 at 01:56

17 Answers17

157

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.

Igor Popov
  • 9,795
  • 7
  • 55
  • 68
Paulo Sousa
  • 1,587
  • 1
  • 9
  • 2
  • 8
    Think of it this way. If you, as a developer consume a .dll with Models in you certainly wouldn't be re-writing them to support INotifyPropertyChanged. – Lee Treveil Feb 03 '11 at 16:24
  • 2
    Strongly agree with you. Like me, you might also be pleased to find out that offical MVVM documentation (Model section) agrees with us. :-) – Noldorin Sep 29 '11 at 21:21
  • "However, tehre are different ways of achieving things but i would always argue in favour of simplicity and avoid redundancy." Very important. – Bastien Vandamme May 29 '12 at 13:32
  • 2
    `INotifyPropertyChanged` is part of the `System.ComponentModel` namespace which is for "**run-time and design-time behavior of components and controls**". **DO NOT USE** `INotifyPropertyChanged` in Models, just in ViewModels. Link to docs: https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel – Igor Popov May 02 '18 at 14:30
  • @IgorPopov doesn't make sense IMO, it's in System.ComponentModel namespace which is for "run-time and design-time behavior of components and controls" so what? – akjoshi Jul 03 '18 at 12:51
  • @akjoshi because you introduce a dependency on the view from the model - which you are supposed to avoid! – Igor Popov Jul 04 '18 at 05:58
  • 2
    Old post, I know, but I often come back to it when starting a new project using MVVM. I've recently started enforcing the Single Responsibility Principle a lot more strictly. A model is to have one responsibility. To be a model. As soon as you add INotifyPropertyChanged to the model, it is not longer following the Single Responsibility Principle. The entire reason the ViewModel exists is to let the model be the model, to let the model have a single responsibility. – Rhyous Mar 16 '19 at 16:31
  • @Rhyous Makes sense, but how do you notify the view or view model of changes that happened in the model? When a change in the model is simple, this is not a problem because the view model will likely know which change it was. But imagine that a change in the model causes other model changes to happen (perhaps in a collection). This is where things get tricky without notification. I'm curious how you would handle this. – redcurry Oct 17 '19 at 05:11
  • @redcurry You are looking at the problem from the wrong angle. You should be asking why and how is the model changing? The model should be protected from direct changes by an outside class. A ViewModel, a Controller, a Proxy whatever pattern fits your architecture. All those are a form of a wrapper. If subsystem x is changing a model, then subsystem X was delivered the wrong object. It should be delivered a wrapped object. This is why models should have interfaces. So you can send subsystem x a model that implements the model interface, but what you send is really a wrapped object. – Rhyous Oct 17 '19 at 13:43
  • 3
    @Rhyous Even if the model is wrapped, the model has the ability to change itself in response to some other change in the model. For example, let's say that changing the Salary of an Employee object also causes the Employee's TaxBracket to change. How would the wrapper (like a ViewModel) know that the TaxBracket changed? – redcurry Oct 17 '19 at 14:10
115

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.

akjoshi
  • 15,374
  • 13
  • 103
  • 121
Steven Robbins
  • 26,441
  • 7
  • 76
  • 90
  • 88
    What do you do if a property changes in the model? You need to get it to the view-model somehow. Honest question, I'm dealing with this conundrum right now. – Roger Lipscombe Jan 18 '10 at 17:15
  • 5
    The EventAggregator in the the Prism code is a good alternative to INotifyPropertyChanged on the model, with a custom property changed event type. The event code in that project supports forwarding events between background and UI threads, which can sometimes be an issue. – Steve Mitcham Feb 12 '10 at 19:48
  • 2
    @Roger - as a small concession to your usage, you could an an event that the viewmodel can hook into that will get called when your UI updates. – Steve Mar 24 '10 at 21:21
  • 56
    INotifyProperyChanged is not WPF specific, it lives in the System.ComponentModel namespace, I have used it in WinForms applications, also INotifyPropertyChanged has been in .Net since 2.0, WPF has only been around since 3.0 – benPearce Mar 04 '11 at 06:03
  • 43
    I'm a fan of putting INotifyPropertyChanged in both the MODEL and the VIEWMODEL. I can't think of a reason not to do this. Its an elegant way of informing the VIEWMODEL of when background changes have happened in your MODE that affect the VIEWMODEL just like its used to inform the VIEW and there have been changes to the VIEWMODEL. – ScottCher Apr 29 '11 at 21:47
  • 7
    @Steve - about informing the ViewModel that a Model's property has changed, it seems like INotifyPropertyChanged works just fine as "an event that the viewmodel can hook into". Why not use it? – skybluecodeflier Jun 30 '11 at 21:32
  • 1
    INotifyPropertyChanged has nothing to do with WPF, but instead deals with data binding. DependencyProperties are the WPF solution to binding changes. INotify is useful even outside of UI, say for example you wanted something in your model to listen for changes to a settings object. If your settings object implements INotify, then instead of figuring out who uses settings and telling them to update, classes that use settings wait for settings itself to publish an update. – Mranz Jun 26 '12 at 20:44
  • 2
    @Roger and anyone else wondering about this: I ended up implementing INotifyPropertyChanged in both my Model and ViewModel. I then subscribe to the Model's PropertyChanged event from my ViewModel so it can also raise the PropertyChanged event so the bindings on the GUI are updated accordingly. See the answer on http://stackoverflow.com/questions/5821956/mvvm-model-to-viewmodel-communication for more details. – Kyle Tolle Nov 15 '12 at 17:36
  • 1
    I've had to put INotifyPropertyChanged on models so my collections of Models get updated properly. I couldn't get property changes in a single record of a larger collection to populate to the view without putting it in the model. – Ebsan Feb 12 '15 at 03:48
  • What If I have `ObservableCollection` of models, and I change some model inside? – Konrad Mar 29 '18 at 12:15
  • 2
    What if your model is used by several different Views, hence several different ViewModels? Then, when a ViewModel changes the model, that change needs to be propagated to other ViewModels somehow. That's why I think it is okay to implement a notification mechanism in the model as well. – Canol Gökel Oct 22 '21 at 07:50
31

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.

Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37
Soni Ali
  • 18,464
  • 16
  • 44
  • 53
  • That first sentence sums up the optinions of the other answers pretty well, imo. => UPVOTE! – j00hi Feb 12 '15 at 11:09
13

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.

quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
Rhyous
  • 6,510
  • 2
  • 44
  • 50
  • 4
    That's great if your data only changes when the DataController changes it. If the data comes from a database or some other datastore that can provide another avenue for change, you may need to have a way to inform the VIEWMODEL (DataController in your pattern) and VIEW when that's happened. You can either poll using the DataController or push from some external process to your DataModel and allow your DataModel to send change notifications to your DataController. – ScottCher Apr 29 '11 at 21:53
  • 5
    You are exactly right. Design patters are very high level. Most the time the design pattern leads you to do things right, but every now and then they turn you the wrong way. You should never avoid doing something right because it is outside your design pattern. – Rhyous May 17 '11 at 20:55
  • You would also push to your DataController as it controls and the data model and would tell it to update. – Rhyous Mar 16 '19 at 16:33
  • Also, Model in MVVM should be kept specific to as needed by UI (e.g. DTO). So any DB or complex business logic should happen in a different layer, and then a crude data should be provided via the view model. – Code Name Jack Jun 12 '19 at 12:24
10

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.

akjoshi
  • 15,374
  • 13
  • 103
  • 121
9

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.

Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37
Steve Mitcham
  • 5,268
  • 1
  • 28
  • 56
  • 3
    How exactly do you propagate Model's OnPropertyChanged to ViewModel's OnPropertyChanged? I have a problem when ViewModel has different property names than Model - some kind of name-to-name mapping would be needed then, right? – Martin Konicek Jul 08 '09 at 21:18
  • It's not anything real sophisticated, we simply forward the events. I suppose if the names were different then a lookup table could be used. If the change weren't a one-to-one mapping, then you could simply hook the event and then fire the necessary events in the handler. – Steve Mitcham Jul 09 '09 at 04:24
5

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

dzendras
  • 4,721
  • 1
  • 25
  • 20
3

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

Andrey Khataev
  • 1,303
  • 6
  • 20
  • 46
3

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

akjoshi
  • 15,374
  • 13
  • 103
  • 121
John D
  • 31
  • 1
  • 5
    The quote is open to interpretation. I think you should add your interpretation, to make your answer clear :-) – Søren Boisen May 21 '15 at 10:55
  • @John D: That article just gives one interpretation of MVVM and a way to implement it, it doesn't defines MVVM. – akjoshi Apr 18 '19 at 08:23
  • Moreover, if you read the full article it defines the Model class like this: "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 class, which provides an implementation of the INotifyCollectionChanged interface." – akjoshi Apr 18 '19 at 08:24
3

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'

Steve Dunn
  • 21,044
  • 11
  • 62
  • 87
2

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.

1

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.

dandan78
  • 13,328
  • 13
  • 64
  • 78
Anand Kumar
  • 395
  • 2
  • 7
  • 18
  • Due to all the disadvantages that you listed, We just decided that it was a WRONG decision in our relatively large WPF project to implement INPC in models. They should deal only with persistence layer. All other things like validation, change notification and calculated properties should be handled in ViewModel. Now I clearly understand that repeating model properties in ViewModel is NOT always a violation of DRY principle. – try2fly.b4ucry Apr 13 '20 at 08:54
1

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.

akjoshi
  • 15,374
  • 13
  • 103
  • 121
Adam
  • 3,815
  • 29
  • 24
0

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.

0

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

akjoshi
  • 15,374
  • 13
  • 103
  • 121
Syed
  • 953
  • 1
  • 8
  • 11
  • 1
    emm.. no. Model can't be xml file or database. And model is not used to give the data. Otherwise it should be called not "model" but "data"..? Model is used to describe the data. Quite self explainatory, isn't it? :) – Taras Jan 31 '18 at 20:15
  • 1
    If you have a better answer, pls share! we're all here to share out knowledge and not to compete – Adam Mar 30 '18 at 16:46
0

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.

Dummy01
  • 1,985
  • 1
  • 16
  • 21
0

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.

akjoshi
  • 15,374
  • 13
  • 103
  • 121
Bram
  • 61
  • 2