In my previous post I mentioned that I had used the Model-View-ViewModel approach to building WPF applications.
In this series of blog posts I will describe this pattern, and show you how to build a small sample application using it within the context of Silverlight. I have folded a bunch of base classes and helper classes into my open source Silverstone framework and these will be used extensively.
What is Model-View-ViewModel
I am assuming that those of you reading this post are familiar with the Model View Controller pattern and have probably used it in some form of ASP.NET or WinForms application. If not then you might want to check out Martin Fowler's article on GUI Architectures for an in depth technical appraisal, or this page on the MSDN site for more information.
The Model-View-ViewModel (or MVVM) pattern is a form of MVC specifically catered for scenarios where you have a very strong data binding ability within the framework, and also one where you want to give your designers the freedom to design the view completely themselves.
Let's explain the three components now:
Model - The Models are the classes which represent the domain on which the application is processing/interacting with. I often refer to these as DataModels, as they are modelling the data in the application, and usually contain some kind of business rules and validation logic.
View - The Views are simply the classes which the render the graphical elements to the user and allow him to interact with the application. They are ideally implemented in 100% markup, although in practise there will end up being some code there too!
ViewModel - The ViewModels are the new kids in town for those of you familiar with traditional MVC/MVP. They essentially take the part of the controller or presenter, and are named as such because they "model the view". Each ViewModel is therefore built for a specific View, and contains all the data and behaviour logic which that View requires to interact with the data models.
In an MVC application, the Controller will typically respond to an event when notified by the view, such as a "Save" button being clicked. It will usually then interact with the model in some way, e.g. reading some values from the view and applying them to the model. Finally it will notify the view of something. For example, it may tell it to display a "your model was saved" message to the user, or alternatively to display a validation warning if something went wrong.
The ViewModel has the same responsibility as the controller, but it handles that responsibility in a different way. Firstly, it makes use of the rich binding provided by the platform by exposing data to the View and raising property changed notifications when that data changes. It also expects the view to use two way binding to push changes direcly back to those properties. Only the data which is required for that specific view is exposed. This will generally include the models which the user needs to view or edit as well as controlling properties which tell the view which state it is in. For example the ViewModel may expose a boolean property which tells the view that it is in the process of saving the DataModel.
At the same time, the ViewModel exposes Commands for the View to execute. It does so in such a way that the commands can be bound directly to UI elements (such as buttons). It is the commands which are responsible for handling user interactions. For example , a save command may be exposed which saves whichever changes users have made to the data models. See my previous blog post for more information on Commands in Silverlight
In Silverlight and WPF terms, the important point to take home is that the ViewModel is the DataContext of the View. This is the key enabler of all the data binding I have been referring to!
And that's really it for now. I hope this makes sense a summary for the architecture pattern we are trying to follow. If you have any questions please let me know.
In the next part of this series, I will begin walking through how to develop a small application using this pattern under Silverlight.
Have a great day!