views:

107

answers:

4

Im struggling to understand the ViewModel part of the MVVM pattern. My current approach is to have a class, with no logic whatsoever (important), except that it implements INotifyPropertyChanged. The class is just a collection of properties, a struct if you like, describing an as small part of the data as possible. I consider this my Model.

Most of the WPF code I write are settings dialogs that configure said Model. The code-behind of the dialog exposes a property which returns an instance of the Model. In the XAML code I bind to subproperties of that property, thereby binding directly to the Model's properties. Which works quite well since it implements the INotifyPropertyChanged. I consider this settings dialog the View.

However, I havent really been able to figure out what in all this is the ViewModel. The articles Ive read suggests that the ViewModel should tie the View and the Model together, providing the logic the Model lacks but is still to complex to go directly into the View. Is this correct? Would, in my example, the code-behind of the settings dialog be considered the ViewModel?

I just feel a bit lost and would like my peers to debunk some of my assumptions. Am I completely off track here?

+2  A: 

Since your model fits perfectly into your view, i.e., your view (settings dialog) can bind directly to the model's data structures, you are in the lucky situation of not needing a view model.

There are, however, many other cases where this is not the case: Imagine having a view that is a direct mapping of a database table, but you want a user interface which does not exactly match this abstraction.

Taking your example "settings dialog" example, let's say your model directly maps to a database table with setting_name, setting_value fields. In your view, however, you don't want the user to fill in some grid; rather, you want the user to fill in some "User Name", "Mail address", etc. fields. In that case, you could create a view model that exposes properties like UserName, MailAddress and internally maps them to your model.

Heinzi
I see. So doing those remappings directly in the View (or rather in the code-behind of the setting dialog) would be considered bad practice?
mizipzor
It's not "bad practice" it's just not MVVM. Whether or not that design pattern works for this part of this application is a much broader question. MVVM is much hyped these days, but IMO is rarely used effectively in practice.
hemp
@hemp: +1, that's exactly what I was about to answer.
Heinzi
@hemp: I agree that MVVM is all the hype right now, but since there are so many (way to many if you ask me) ways to do a single thing in WPF, I feel that I need a pattern to fall back on to help me navigate the GUI codebase.
mizipzor
@mizipzor: That's exactly it: If it helps you to organize your codebase (by separating concerns between UI code (= view codebehind) and data transformation code (= ViewModel)), then it's usually a good idea to use it.
Heinzi
A: 

The ViewModel is typically used to bind to those values which affect the visual appearance and behavior of your View. In this particular case, you would further abstract your model to represent only the setting data, and none of the behavior. For instance, if you have a checkbox which, when checked, makes several sliders invalid, the logic for enabling/disabling those sliders would be provided by the ViewModel, not the View itself and not the Model itself.

One helpful way to look at breaking up your designs into MVVM is to ask yourself, how would I unit test the behavior of my view, assuming I can't interact with the view from my test? Often you'll discover that most of your behavior is actually tied up in the view and is largely untestable apart from functional tests.

hemp
+1  A: 

What you consider your Model is in fact your ViewModel. The ViewModel is the class that supports the View. It often has an API that targets a particular technology (such as WPF or SilverLight).

Thus, the ViewModel can have ICommand properties, and properties that provide Colors or Brushes for databinding. It can also have properties that control whether specific controls are enabled or disabled, or visible at all.

All this is very View-oriented logic, and hence lives in the ViewModel.

In all but toy applications, you also need a proper Domain Model, but you don't want to pollute this model with all this View-oriented logic. It doesn't belong there - you might want to reuse the Domain Model to expose web services or a web site, and INotifyPropertyChanged, ICommand properties and whatnot does not belong there.

The Domain Model is your Model in the MVVM pattern. The ViewModel provides a bridge between the View and the Model.

Mark Seemann
So if I understand you correctly, to make my Model a proper Model, I should get rid of INotifyPropertyChanged? Making it very similar to a C struct? Just a bunch of values bundled together?
mizipzor
You still need a ViewModel with all the INPC stuff there, but in MVVM you also need a Model. You need both, but no-one says that a VM can't have any behavior. My VMs usually have lots of behavior, but it's *UI-specific* behavior.
Mark Seemann
A: 

The Model is the model of your data. The ViewModel is the model of your View. The View is a Window or Page or DataTemplate, generally defined in XAML.

There's tight coupling between the view and the view model. Objects in the view are bound to properties of the view model. If you change the design of the view, you'll change the design of the view model. Generally speaking, the view model is what you use instead of code-behind.

There's tight coupling between the view model and the data model. A view model instance typically contains a reference to an instance of the data model. Properties of the view model update properties in the data model instance, typically when they're set. (Not necessarily, though. It's not uncommon, for example, for a view model to implement a Command that updates the underlying instance of the data model, or to implement IEditableObject.)

There's no coupling between the view and the model. You can generally make substantial changes to the model which, as long as they don't have user interface implications, also don't require changes to the view. You can generally make substantial changes to the functionality of the UI without affecting the data model (unless those changes actually require new functionality in the data model).

Robert Rossney