In MVVM should the ViewModel or Model implement INotifyPropertyChanged?
Asked Answered
S

17

179

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?

Sunglass answered 21/4, 2009 at 11:57 Comment(1)
if you do implement INPC, give github.com/Fody/PropertyChanged a try - it will save you weeks of typing.Halfprice
L
116

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.

Lakeesha answered 21/4, 2009 at 12:9 Comment(11)
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.Folkestone
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.Medicare
@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.Filibeg
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.0Nevanevada
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.Palpable
@Filibeg - 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?Mahau
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.Embry
@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 #5822456 for more details.Amann
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.Guyon
What If I have ObservableCollection of models, and I change some model inside?Nernst
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.Bilow
M
159

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.

Muzz answered 10/5, 2010 at 16:49 Comment(10)
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.Gorlin
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.aspx> (Model section) agrees with us. :-)Lavettelavigne
"However, tehre are different ways of achieving things but i would always argue in favour of simplicity and avoid redundancy." Very important.Humoral
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: learn.microsoft.com/en-us/dotnet/api/system.componentmodelStutsman
@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?Issykkul
@Issykkul because you introduce a dependency on the view from the model - which you are supposed to avoid!Stutsman
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.Wiseman
@Wiseman 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.Rote
@Rote 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.Wiseman
@Wiseman 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?Rote
L
116

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.

Lakeesha answered 21/4, 2009 at 12:9 Comment(11)
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.Folkestone
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.Medicare
@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.Filibeg
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.0Nevanevada
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.Palpable
@Filibeg - 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?Mahau
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.Embry
@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 #5822456 for more details.Amann
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.Guyon
What If I have ObservableCollection of models, and I change some model inside?Nernst
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.Bilow
P
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.

Pandit answered 4/5, 2009 at 12:35 Comment(1)
That first sentence sums up the optinions of the other answers pretty well, imo. => UPVOTE!Widmer
W
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.

Wiseman answered 1/1, 2011 at 16:46 Comment(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.Palpable
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.Wiseman
You would also push to your DataController as it controls and the data model and would tell it to update.Wiseman
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.Novelistic
I
11

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.

Issykkul answered 15/12, 2015 at 9:6 Comment(0)
M
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.

Medicare answered 21/4, 2009 at 12:55 Comment(2)
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?Beatification
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.Medicare
R
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".

Rheostat answered 19/2, 2013 at 8:9 Comment(0)
D
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'

Diphthong answered 21/4, 2009 at 12:48 Comment(0)
O
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...

Oxime answered 10/11, 2009 at 14:7 Comment(0)
F
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. "

Forde answered 24/8, 2013 at 6:46 Comment(3)
The quote is open to interpretation. I think you should add your interpretation, to make your answer clear :-)Albanian
@John D: That article just gives one interpretation of MVVM and a way to implement it, it doesn't defines MVVM.Issykkul
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."Issykkul
T
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.

Tallu answered 5/4, 2019 at 16:40 Comment(0)
B
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.

Bigname answered 20/9, 2011 at 17:49 Comment(1)
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.Alluring
O
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.

Olney answered 30/11, 2011 at 11:48 Comment(1)
What about models with several properties? you are repeating code in VM.Taliesin
L
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

Legitimacy answered 16/7, 2011 at 2:33 Comment(2)
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? :)Threesome
If you have a better answer, pls share! we're all here to share out knowledge and not to competeOlney
I
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.

Icelandic answered 23/8, 2011 at 7:15 Comment(0)
L
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.

Lamoureux answered 14/10, 2011 at 5:1 Comment(0)
O
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.

Ong answered 28/2, 2019 at 13:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.