About a year ago I did a session here at work going over the Task Parallel Library (TPL), it’s benefits and where it works and doesn’t work. To illustrate a lot of the TPL I wrote a simple WPF application with standard code-behind that contained a ton of code samples that demonstrated the concepts I was discussing. I’ve been thinking of doing a basic introduction to MVVM as well as expanding on some of the posts I’ve written here regarding the TPL and finally decided to just write a TPL Sampler application utilizing MVVM. The application could be generalized more than it is but since I wanted to work specifically with the TPL there are some choices I made that may seem a bit odd in general but work given the scope of the application.
So what is MVVM? MVVM stands for Model-View-View Model and derives from the MVC pattern. Wikipedia has a pretty good write up of it that goes fairly in depth into the theory of the pattern. MVVM grew from MVC to take advantage of the data binding abilities of WPF. As a generalization you can consider the Model, whether it’s a data object derived from a database abstraction layer or, in my case, a bit of sample code to run, the object that you are working with. The View is all the GUI components. Finally, the View Model works as the controller to manage interactions between the Model and the View.
So what are the advantages of MVVM? The biggest is a separation of concerns. By this I mean that your data layer can cleanly exist separate from your GUI. This allows for easy integration of unit test on the models and view models as well as easily allowing development to proceed in different areas of the application. All standard advantages to an n-tiered approach to application development apply.
So what are the disadvantages of MVVM? It can get complex pretty easy. There are so many things we take advantage of being able to do right in code-behind that aren’t “proper” within MVVM. While you can do anything in MVVM that you can do in regular code-behind, sometimes you have to go to pretty great lengths to do so. As an example, specifying custom click-events on leaf nodes in a tree where each branch has an arbitrary depth. This may seem contrived but this is a problem I’ve had to solve.
I would argue that MVVM isn’t the end-all, be-all solution to application development in WPF and I think most people would agree with me. I would also argue that you can blend both MVVM and the standard observer pattern with code-behind (which I’ll discuss when going over the sample application. It’s called a composite application and happens fairly often).
It’s an invaluable tool that can greatly ease development and maintenance but it is just one tool. That being said, I can’t think of many application scenarios where it isn’t applicable. Applications are generally data driven. For the most part we’re getting data, manipulating it and then doing something with the result. So why not have a framework in place that takes advantage of the binding that WPF presents?
The sample application (which is here and linked below) is probably one of the simplest MVVM projects you will find. It’s even a bit simpler than Microsoft’s MVVM QuickStart sample application.
Starting with References:
The following references were added beyond the standard references VS adds when creating a default project.
The Prism libraries are included in the lib directory of the project and are from the Microsoft patterns & practices: Prism site. The Prism libraries aren’t an MVVM framework unto themselves but make utilizing a general MVVM approach easier. I had to add the following redirect in my app.config to compile without warnings because of how the Prism libraries are compiled:
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Windows.Interactivity" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="126.96.36.199" newVersion="188.8.131.52"/> </dependentAssembly> </assemblyBinding> </runtime>
The ServiceLocation reference is needed by the Prism libs. It too is included in the lib directory but can also be downloaded from Microsoft patterns & practices: CommonServiceLocator
If you look at the MainWindow.xaml you’ll see that the only thing in it is:
<Grid> <Views:SamplerView /> </Grid>
The SamplerView contains all our GUI elements for enabling/disabling samples, adding an image for samples to use and the buttons for running the sample. In the next post I’ll work on explaining the SamplerView in more detail.