In MVVM should the ViewModel or Model implement INotifyPropertyChanged?

53,002

Solution 1

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 2

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 3

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

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

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.

Share:
53,002

Related videos on Youtube

Angry Dan
Author by

Angry Dan

web/software developer, .NET, C#, WPF, PHP, software trainer, English teacher, have philosophy degree, love languages, run marathons my tweets: http://www.twitter.com/edward_tanguay my runs: http://www.tanguay.info/run my code: http://www.tanguay.info/web my publications: PHP 5.3 training video (8 hours, video2brain) my projects: http://www.tanguay.info

Updated on May 18, 2020

Comments

  • Angry Dan
    Angry Dan about 4 years

    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?

  • Martin Konicek
    Martin Konicek almost 15 years
    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?
  • Steve Mitcham
    Steve Mitcham almost 15 years
    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.
  • Roger Lipscombe
    Roger Lipscombe over 14 years
    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.
  • Steve Mitcham
    Steve Mitcham over 14 years
    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
    Steve about 14 years
    @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.
  • Lee Treveil
    Lee Treveil over 13 years
    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.
  • benPearce
    benPearce about 13 years
    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
  • ScottCher
    ScottCher about 13 years
    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
    ScottCher about 13 years
    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.
  • Rhyous
    Rhyous about 13 years
    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.
  • skybluecodeflier
    skybluecodeflier almost 13 years
    @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?
  • Noldorin
    Noldorin over 12 years
    Strongly agree with you. Like me, you might also be pleased to find out that offical MVVM documentation <msdn.microsoft.com/en-us/library/gg405484%28v=pandp.40%29.a‌​spx> (Model section) agrees with us. :-)
  • Bastien Vandamme
    Bastien Vandamme about 12 years
    "However, tehre are different ways of achieving things but i would always argue in favour of simplicity and avoid redundancy." Very important.
  • Mranz
    Mranz almost 12 years
    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.
  • Kyle Tolle
    Kyle Tolle over 11 years
    @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 stackoverflow.com/questions/5821956/… for more details.
  • Ebsan
    Ebsan over 9 years
    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.
  • j00hi
    j00hi over 9 years
    That first sentence sums up the optinions of the other answers pretty well, imo. => UPVOTE!
  • Søren Boisen
    Søren Boisen about 9 years
    The quote is open to interpretation. I think you should add your interpretation, to make your answer clear :-)
  • Taras
    Taras over 6 years
    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? :)
  • Konrad
    Konrad about 6 years
    What If I have ObservableCollection of models, and I change some model inside?
  • Luis
    Luis about 6 years
    What about models with several properties? you are repeating code in VM.
  • Adam
    Adam about 6 years
    If you have a better answer, pls share! we're all here to share out knowledge and not to compete
  • Igor Popov
    Igor Popov about 6 years
    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: docs.microsoft.com/en-us/dotnet/api/system.componentmodel
  • akjoshi
    akjoshi almost 6 years
    @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?
  • Igor Popov
    Igor Popov almost 6 years
    @akjoshi because you introduce a dependency on the view from the model - which you are supposed to avoid!
  • Rhyous
    Rhyous about 5 years
    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
    Rhyous about 5 years
    You would also push to your DataController as it controls and the data model and would tell it to update.
  • akjoshi
    akjoshi about 5 years
    @John D: That article just gives one interpretation of MVVM and a way to implement it, it doesn't defines MVVM.
  • akjoshi
    akjoshi about 5 years
    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<T> class, which provides an implementation of the INotifyCollectionChanged interface."
  • Code Name Jack
    Code Name Jack almost 5 years
    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.
  • redcurry
    redcurry over 4 years
    @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.
  • Rhyous
    Rhyous over 4 years
    @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.
  • redcurry
    redcurry over 4 years
    @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?
  • try2fly.b4ucry
    try2fly.b4ucry about 4 years
    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.
  • Canol Gökel
    Canol Gökel over 2 years
    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.