In MVVM should the ViewModel or Model implement INotifyPropertyChanged?
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.
Related videos on Youtube
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, 2020Comments
-
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 implementsINotifyPropertyChanged
.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 getCommandSink
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?
-
CAD bloke about 8 yearsif you do implement INPC, give github.com/Fody/PropertyChanged a try - it will save you weeks of typing.
- You have to put the
-
Martin Konicek almost 15 yearsHow 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 almost 15 yearsIt'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 over 14 yearsWhat 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 over 14 yearsThe 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 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 over 13 yearsThink 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 about 13 yearsINotifyProperyChanged 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 about 13 yearsI'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 about 13 yearsThat'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 about 13 yearsYou 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 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 over 12 yearsStrongly 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.aspx> (Model section) agrees with us. :-)
-
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 almost 12 yearsINotifyPropertyChanged 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 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 over 9 yearsI'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 over 9 yearsThat first sentence sums up the optinions of the other answers pretty well, imo. => UPVOTE!
-
Søren Boisen about 9 yearsThe quote is open to interpretation. I think you should add your interpretation, to make your answer clear :-)
-
Taras over 6 yearsemm.. 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 about 6 yearsWhat If I have
ObservableCollection
of models, and I change some model inside? -
Luis about 6 yearsWhat about models with several properties? you are repeating code in VM.
-
Adam about 6 yearsIf you have a better answer, pls share! we're all here to share out knowledge and not to compete
-
Igor Popov about 6 years
INotifyPropertyChanged
is part of theSystem.ComponentModel
namespace which is for "run-time and design-time behavior of components and controls". DO NOT USEINotifyPropertyChanged
in Models, just in ViewModels. Link to docs: docs.microsoft.com/en-us/dotnet/api/system.componentmodel -
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 almost 6 years@akjoshi because you introduce a dependency on the view from the model - which you are supposed to avoid!
-
Rhyous about 5 yearsOld 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 about 5 yearsYou would also push to your DataController as it controls and the data model and would tell it to update.
-
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 about 5 yearsMoreover, 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 almost 5 yearsAlso, 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 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 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 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 about 4 yearsDue 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 over 2 yearsWhat 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.