Latest Tweet:
  • Loading...

Separation of concerns is a key principle in object oriented software design. For GUI applications the separated presentation patterns help you separate your View, Model and interaction logic. Personally I’m a big fan of the Model-View-ViewModel for Silverlight and WPF applications as it enables heavy use of data binding. However, in some cases it is useful to combine the MVVM pattern with other members of the separated presentation family of patterns.

I’ve done a fair bit of blogging about the Model-View-ViewModel pattern in a Silverlight 2 context and gotten some good feedback on that. One of the questions I get asked often is how to implement scenarios like multi page navigation, or complex user interactions like and drag and drop within a Model-View-ViewModel context. It turns out that in many cases the problem is that the developer is so focused on implementing the pattern that they fail to see alternative approaches to solve their problems. I’m as guilty of this as anyone – once you get a new hammer everything becomes a nail.

The Model-View-ViewModel belongs to a family of software patterns commonly referred to as separated presentation patterns. These are patterns that try to clearly separate the different concerns of your GUI application. In most cases they separate the View (user interface), the Model (domain and/or data model) and “something else”, which in many cases is the main different between these patterns. Model-View-Controller is one; perhaps the original separated presentation pattern, which has gotten a lot of attention lately as it is proven to be very effective in web development. The popular Ruby on Rails framework is based on this pattern, and Microsoft just released a beta of their ASP.NET MVC framework implementation. The stateless request-response nature of the web makes the MVC pattern a good fit for web applications. You may have a front controller routing an incoming web request to the correct Controller, which in turn makes a decision on what to do. The Controller may fetch some data from the Model and pass it onto a View which will render the HTML.

Another popular pattern is the Model-View-Presenter, which comes in two flavors; Passive View and Supervising Controller. This pattern has many applications and implementations. The Passive View is about reducing the View to a dumb slave driven by the Controller. The View implements a finely grained interface, with properties and methods like Name, Age, Address, without any references to UI framework specific types. The Controller drives the View by setting these properties. The benefit of this approach is that the Controller becomes highly testable, and you can reuse the same Controller in different UI environments. You may implement the View interface for different UI platforms, like web, a Windows client or even a mobile device. The drawback of the Passive View is that you may not leverage the power of the UI platform you are targeting, for instance by using data binding if you’re targeting WPF or Silverlight.

The Supervising Controller flavor of MVP lets the View deal with simple synchronization and mapping against the Model. User input and complex view logic is handled by a Supervising Controller class. This lets you leverage some of the capabilities of the UI platform by accessing the Model directly, while keeping complex code that needs unit tests in a separate class. Later I will show this pattern can be combined with the Model-View-ViewModel pattern to implement drag-and-drop behavior in a WPF application.

Flickr Uploader Sample Application

To show how the Supervising Controller and the Model-View-ViewModel pattern can be combined I’m going to create facetious Flickr Photo Uploading application. I’m not going to implement any real integration with Flickr, but rather focus on how to implement drag-and-drop of photos to upload and how this fits in with the MVVM and Supervising Controller patterns. I picked this sample because I was faced with this exact problem earlier this week on one of the projects I’m working on. It’s a WPF application where we’re using the MVVM pattern for most of it. One of the requirements of the application was support for drag-and-drop import of files from client’s computer. It was not entirely obvious how to implement this in a true MVVM way, and it turned out the addition of a Supervising Controller was a good solution this time.

I’m not going to spend too much time covering the Model-View-ViewModel pattern in depth as I have already done that earlier. I would also recommend checking out Nikhil Kothari and John Gossmans blog posts for more information about the Model-View-ViewModel pattern. However, I will briefly touch on the key concepts of the pattern. The ViewModel part of the pattern is a View-specific class that supports data binding. Each View gets its DataContext property set to an instance of a ViewModel. The different UI elements in the View are data bound to properties on the ViewModel class. The ViewModel notifies the View of any changes by implementing the INotifyPropertyChanged interface and fire the PropertyChanged event whenever the underlying Model changes, or by using an ObservableCollection<T> for collections of data. The View interacts with the ViewModel by executing Commands. For instance clicking the Submit Photos button will execute the SubmitPhotos Command, which will push data back to the underlying Model. The following illustration shows a screenshot of the sample application, and a diagram of how the MVVM pattern is implemented.

FlickrUploadrMVVM

FlickrUploadrXAML

The next piece of functionality that needs to be implemented is drag-and-drop. I want to be able to drag files from my hard drive and onto the application. To implement this I need to handle the DragOver and Drop events on my MainWindow class. In my implementation of the MVVM pattern my View holds a reference to the ViewModel, but the ViewModel does not reference the View. So there is no obvious way for my ViewModel to handle these events. I could extend my ViewModel and add a property to give the ViewModel a reference to the View consuming it. I’m not sure if this is a good idea, or if this functionality should be handled by the ViewModel in the first place. Instead I decide to use a Supervising Controller to implement this functionality. The Supervising Controller class accepts the View to control in its constructor. Instead of taking a dependency on the concrete View class I implement a simple IDragDropSurface interface, which has the DragOver and Drop events. The Supervising Controller is created in the View constructor.

FlickrUploadrMainWindowCodeBehind

The Supervising Controller is responsible for listening to the DragOver and Drop events. When the Drop event executes the Supervising Controller will execute the Import Photos command. This enables the Supervising Controller to communicate with the ViewModel in a loosely coupled way. The ViewModel is responsible for iterating over the list of files and creating FileInfo objects that gets added to the ObservableCollection of FileInfo objects. The View is data bound to this collection and the ItemsControl data template will display the imported photos.

DragDropPresenter

This is an updated diagram showing how the Supervising Controller relates to the view and the View Model.

FlickrUploadrDiagram

Summary

Applying separated presentation patterns in your GUI applications is a great way to achieve separation of concerns, decoupling of components and higher level of testability. In this blog post you’ve seen how the Supervising Controller pattern can be combined with a Model-View-ViewModel pattern to implement drag-and-drop functionality. The specific example uses WPF, but the same concepts apply for Silverlight 2 applications as well.

Monday, November 17, 2008 2:41:52 AM (W. Europe Standard Time, UTC+01:00)
Nice post... I agree that more often than not a couple of patterns need to be combined as apps get more functional than demos.

I also personally believe in the behavior concept, as a nice way to encapsulate logic and attach it to the view. For example, in your sample above one possible approach might be to implement a FileDropBehavior and attach it to the view, and invoke the view model's AddFiles method (or execute its ImportPhotos command) when the behavior raises its FilesDropped event.

The fun thing with these patterns is there are multiple ways to go about implementing an app.
Monday, November 17, 2008 6:02:12 AM (W. Europe Standard Time, UTC+01:00)
Thanks for the comment Nikhil! Awesome that you read me blog - I've been following your work since the early days of ASP.NET 1.0 and the WebMatrix tool :)

I agree - attached behaviors could be a good solution to this problem. Attached behaviors would have some additional benefits over my Supervising Controller implementation. For one I would be able to attach this behavior through XAML without having to change my code behind. Te behavior could target a control, and have properties to set the commands to execute - like you suggests.

Another benefit of behaviors for encapsulation (over say MVP/MVVM/MVC style approaches) is that they are probably easier to make "general purpose" and reusable across projects. My DragDrop Controller solves the problem, but would not be something I brought on to the next project as a reusable component. With behaviors you can build up libraries (like you're doing with the SilverlightFX project).

A third benefit of having this in XAML is the possibility for extended tooling support. I love patterns that can be tooled (like the VSM and Part Model for Silverlight controls). Behaviors and Effect libraries implemented in a certain way could be picked up by Blend, and designers would be able to attach basic behaviors in an easy way.

So yeah - definitely an interesting suggestion. And I agree - it's fun how these patterns can be combined together. I think the Composite WPF StockTrader RI does a good job of showing different separated presentation patterns working together in one application.
Monday, November 17, 2008 8:41:06 PM (W. Europe Standard Time, UTC+01:00)
I've faced the problem before of needing the ViewModel to communicate with the View but not wanting it to have a dependency on the View.

A pattern that I've used before is for a ViewModel to define an IViewOperations interface (each type of ViewModel that needs it defining its own interface). The View implements this interface then injects itself into a ViewOperations property on the ViewModel.

The ViewModel can then use this for triggering things like animations, which aren't always amenable to databinding.
Wednesday, November 19, 2008 2:16:59 PM (W. Europe Standard Time, UTC+01:00)
Thank you Jonas for all the great articles on architecture - they have really helped.
Thursday, November 20, 2008 2:20:15 AM (W. Europe Standard Time, UTC+01:00)
@Samuel Thanks for the suggestion - yeah that sounds like a good way to do it. By using Property based Injection you can still get the benefit of setting the ViewModel declaratively through XAML (and thus getting design time support in Blend). Then in the View constructor you can set the ViewOperations property on the ViewModel. I like it :)

@David I'm glad you like it and find my writing helpful! Feedback like this that keep me blogging :)
Wednesday, November 26, 2008 12:58:14 AM (W. Europe Standard Time, UTC+01:00)
Jonas, very nice post.
I like that you put emphasis on showing that even though ViewModel is a very useful pattern, it should not turn to be a constraint, where other patterns would fit your solution better.
I also tend to use ViewModel as my default pattern, but try not to limit myself to it.
This is also something that we tried to show when building CompositeWPF, because as you can see, the library does not force you to use any of the presentation patterns, and the documentation also suggest a few approaches, and not a one-pattern-to-rule-them-all.
I was also thinking that this could fit very nicely by using attached behaviors in xaml, as Nikhil suggested.
Friday, November 28, 2008 3:25:18 AM (W. Europe Standard Time, UTC+01:00)
Hi Julian,

I've been learning about the Composite WPF, and is actually going to use it for a project I'm involved with. So some of the inspiration to write this blog post came from seeing examples in the RI where you have different modules using different patterns. I think it makes perfect sense, and I really like how the CompositeWPF does not force you down one path for implementing separatedA presentation.

Also glad that you stumbled over my blog - I've been following your blog for some time after getting into CompositeWPF. I like your ICommand implementation for Silverlight, and have recommended it to multiple people who want commanding in a Silverlight context. I'm also impressed with the the progress you have made with Prism2. I have been playing with both drop 5 and 6, and it's really starting to shape up. I expect to do more blogging about Prism2 in the months to come.

Cheers,
Jonas
Name
E-mail
(will show your gravatar icon)
Home page

Comment (Some html is allowed: a@href@title, strike) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview
<September 2010>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789