4

I am building and MVVM application where some of my Models contain the state of realworld-object that their are modelling. The state changes from outside events, e.g. my Model gets information over TCP/IP about a stock that changes, and updates its state to reflect that change.

Now I would like the change to propagate to my View, and the way to do that, is to let my ViewModel know about the change. I can think of two ways of doing this.

One, I let the Model implement INotifyPropertyChanged, and fire the event when the property changes. However, this seems to be frowned upon for some reason.
Two, I implement an event for each property that can change in the Model, events that the ViewModel explicitly can bind to.

What is the preferred way? Are there other ways (better ways) of doing it?

Edit:
I have now read, both in the comment from slugster and here, that having the Model have a state is not the purpose of the model.
However, in John Gossmans original MVVM post, we find: "The Model is defined as in MVC; it is the data or business logic, completely UI independent, that stores the state and does the processing of the problem domain."

Community
  • 1
  • 1
kasperhj
  • 10,052
  • 21
  • 63
  • 106

4 Answers4

1

Option 2 is viable, albeit dirty. You can mitigate the dirtiness somewhat by exposing the public events and functions via an interface, and the viewmodel uses the model only via that interface.

Having said that, the model should be treated as a conduit of information, rather than a container for information. This means that ideally your model should not contain any state information. If you have a persistently open channel in your model that needs to notify other components when something is received then I suggest you use the EventAggregator in Prism - this is a weak event pub/sub system, your viewmodel can subscribe to an event of your choosing, and your model can publish that event when it needs to (along with an appropriate payload).

slugster
  • 49,403
  • 14
  • 95
  • 145
  • The advantage of having the model having a state, is that you can use it in scenarios where there is no view. If the state does not go in the model, it would have to go in the viewmodel. Having a viewmodel without a view seems odd. Having an EventAggregator seems too orthogonal for the problem. – kasperhj Nov 12 '12 at 07:32
1

The model classes typically provide property and collection change notification events through the INotifyPropertyChanged and INotifyCollectionChanged interfaces. This allows them to be easily data bound in the view. Model classes that represent collections of objects typically derive from the ObservableCollection class.

MSDN

I wouldn't say that a Model typically implements INotifyPropertyChanged, but I wouldn't categorically refuse to do so. In simpler - non-PRISM - environments it's totally fine in my opinion.

And then?

To clarify: INotifyPropertyChanged is an interface for the notification in case of a property change, as the name says and most people know. However, it is not more than this, especially it is not WPF specific! Furthermore, as according to the the MVVM principles, the Model should be agnostic of the ViewModel. Therefore, it is clear, that you should use a Publisher(Model)-Subscriber(ViewModel)-pattern (events). That's all. So, as an answer to your question: How to set up the communication between Model/ViewModel depends on your style and the specific task:

If you just want to react on changed properties, just use INotifyPropertyChanged, as that's what it was made for. In the ViewModel, just subscribe to the PropertyChanged-event of the Model and process the changes, which is basically just 'map them forward', that is raise PropertChanged for the ViewModel-property, which is effected by the change of the model property.

Alternatively, if you need to wrap the model changes in a more specific event, lets say 'MyDataUpdated', then I don't see any problem about that as well. Just listen to this event in the ViewModel, and handle it as you wish. That's perfectly fine to.

I hope this helps.

EDIT: As a side-note: I recommend using the PropertyWeaver extension, so that you donÄt mess up your model with all the PropertyChanged-stuff.

Marc
  • 12,706
  • 7
  • 61
  • 97
1

I will go with option1. Keep a reference to the model in your viewmodel, however do not use any properties directly. Instead, populate the viewmodel's own properties from the model.Your view model can listen to the property changing notifications for the concerned properties from the Model, and repopulate its own properties from the model. The model is still UI independent, it is merely notifying property changed.

In my opinion, doing your own publisher-subscriber logic other than inotifypropertychanged could be just an overkill as there might not be any benefits doing that. However, this depends on whether you can afford to have a model reference in the view model and my answer is based on the assumption that you can have a reference of model in view model.

Jimmy
  • 3,224
  • 5
  • 29
  • 47
-1

For for data binding you can use **Binding**

Data Binding Overview

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Zhenia
  • 3,939
  • 3
  • 15
  • 15
  • This doesn't really answer the question - the OP already knows about binding. I would also never advocate binding from the View to the Model in the MVVM pattern. – slugster Nov 12 '12 at 07:12