jump to navigation

Model-View-Presenter and Model-View-ViewModel in Prism March 23, 2009

Posted by wesaday in Programming.
Tags: , , , , , ,
trackback

 Introduction

 One of the most valuable skills a developer can develop is the ability to seperate UI modules, business rules and data access modules so that they are more maintainable. This separation means that the modules can be developed independently of each other without the changes having any impact on other modules. After several years in the business you get kind of tired of making a change and then having to chase down a bug that made its way in your application affecting modules that you never thought your change would touch you will come to appreciate separating out the code into different modules. Prism actually makes this pretty simple.

The first design pattern that will be demonstrated is the Supervising Presenter pattern that most closely resembles the Model-View-Presenter pattern so if you understand the MVP pattern then you should have no problem understanding this. For more information on the Supervising Presenter pattern see the Supervising Presenter topic in the Prism documentation.

A simple diagram for the MVP pattern looks like this:

 

 

 

 

 

MVP diagram

MVP diagram

 

 

 

 

 

The second design pattern that will be demonstrated is the Presentation Model or Model-View-ViewModel pattern.  For more on the Presentation Model pattern see the Presentation Model topic in the Prism documentation.

A simple diagram of the Presentation Model pattern looks like this:

 

 

 

 

 

MVVM diagram

MVVM diagram

 

 

 

 

 

The foundation for this demonstration is the final project from the Getting Started article which you can get here.

First the MVP pattern

The first thing to do is to decide what kind of data that we are going to display in the view and how we are going to display it. For this simple example we are going to display some strings in a ListBox. So the final ChildOneView will look like this:

 

one

The second thing to do is to create some folders within the project to hold the various files that we are going to be creating. This helps to keep the clutter down.  Right click on the ChildOneModule project and add a NewFolder named “Interfaces”. Add two more folders and name them “Presenters” and “Services”. Now we are going to need to create three interfaces, one for the View, one for the Model and one for the Presenter.  After that your project will look something like this

struct1

The interfaces are very simple. The Model interface will expose a collection strings that the view will bind to.

 

 

 

    public interface IChildOneService

    {

        ObservableCollection<string> GetStrings();

    }

 

 

 

 

 

 

The Presenter interface will need to have a reference to the View:

 

 

 

    public interface IChildOnePresenter

    {

        IChildOneView View { get; set; }  

    }

 

 

 

 

 

 

And finally, the View will need to have a reference to the data that the Model is going to expose:

 

 

 

    public interface IChildOneView

    {

        ObservableCollection<string> Model { get; set; }

    }

 

 

 

 

 

 

That pretty much does it for the interfaces. The next thing to do is to create a class that will serve as the Model. Right click the Services folder and add a new class named “ChildOneService”. The service will need to implement the IChildOneService interface that we created earlier.

 

 

 

    public class ChildOneService : IChildOneService

    {

        public ObservableCollection<string> GetStrings()

        {

            ObservableCollection<string> strings = new ObservableCollection<string> { “one”, “two”, “three”};

            return strings;

        }

    }

 

 

 

 

 

 

The GetStrings method will return the string collection and that is what is going to be displayed in the View. It’s important to realize that the data that is displayed could come from anywhere, a file, a database, a web service, etc.

The Presenter class is also very simple. Create a ChildOnePresenter class in the “Presenters” folder and have it implement the presenter interface. The Presenter will need a reference to the view and the model passed to it in the class constructor.

 

 

 

    public class ChildOnePresenter : IChildOnePresenter

    {

        public IChildOneView View { get; set; }

 

        public ChildOnePresenter(IChildOneView view, IChildOneService model)

        {

            View = view;

            View.Model = model.GetStrings();

        }

    }

 

 

 

 

 

 

Open the view code-behind file. Modify the class definition to implement the IChildOneView interface. The view interface is implemented as a property that is used to data bind to. The data is transferred from the ChildOneService class to the View by the Presenter.

 

 

 

   public partial class ChildOneView : UserControl, IChildOneView

    {

        public ChildOneView()

        {

            InitializeComponent();

        }

 

        public ObservableCollection<string> Model

        {

            get

            {

                return DataContext as ObservableCollection<string>;

            }

            set

            {

                DataContext = value;

            }

        }

    }

 

 

 

 

 

 

Open the View XAML file and modify the view to include a listbox and bind the listbox item data source to the string collection.

 

 

 

    <StackPanel>

        <Label Content=”Child one” />

        <ListBox ItemsSource=”{Binding}” />

    </StackPanel>

 

 

 

 

 

 

The last step is to modify the module class. We need to include a reference to the container so that we can notify the container that we have additional classes for it to instantiate. Once that is done, then we register the Model, View and Presenter with the container

 

 

 

    public class ChildOne : IModule

    {

        private readonly IRegionManager _regionManager;

        private readonly IUnityContainer _container;

 

        public ChildOne(IUnityContainer container, IRegionManager regionManager)

        {

            _regionManager = regionManager;

            _container = container;

        }

 

        public void Initialize()

        {

            _container.RegisterType<IChildOneService, ChildOneService>();

            _container.RegisterType<IChildOnePresenter, ChildOnePresenter>();

            _container.RegisterType<IChildOneView, ChildOneView>();

 

            ChildOnePresenter presenter = _container.Resolve<ChildOnePresenter>();

            _regionManager.Regions[“LeftChild”].Add(presenter.View);

        }

    }

 

 

 

 

 

 

If you compile and run the application at this point, you should see a window like the picture up top. That is how to implement the MVP pattern in Prism.

Model-View-ViewModel

The MVVM pattern is implemented in almost the same way. The only real difference is the way the View displays its data. MVVM relies heavily on data binding and Commands to get things done. This article is not going to cover Commands. That is something for another time.

To begin, create folders in the ChildTwoModule project named Interfaces, Services and ViewModels. You should turn out with something that looks like this:

 

struct2

For this example we will need three interfaces, IChildTwoModel, IChildTwoView and IChildTwoViewModel. As in the previous example, the Model will export a list of strings so our interface for the Model will look like this:

 

 

 

    using System.Collections.ObjectModel;

 

    public interface IChildTwoModel

    {

        ObservableCollection<string> GetStrings();

    }

 

 

 

 

 

 

The interface for the ViewModel will need to have a Property that exposes the list of strings to the View. The ViewModel will also need a reference to the View so our interface for the ViewModel will look like this:

 

 

 

    public interface IChildTwoViewModel

    {

        ObservableCollection<string> ModelStrings { get; }

 

        IChildTwoView View { get; }

    }

 

 

 

 

 

 

 The interface for the View will need a way to set the data to display. Since the ViewModel is exposing the data, the View needs a way to data bind the ViewModel to the View:

 

 

 

    public interface IChildTwoView

    {

        void SetModel(IChildTwoViewModel model);

    }

 

 

 

 

 

 

Now, on to the implementation. The Model class needs to implement the IChildTwoModel interface so create a new class in the Services folder named ChildTwoModel and then implement the interface. Remember that the interface is a method named GetStrings and returns a collection of string objects. So your Model class will look like this:

 

 

 

    using Interfaces;

    using System.Collections.ObjectModel;

 

    public class ChildTwoModel : IChildTwoModel

    {

        public ObservableCollection<string> GetStrings()

        {

            ObservableCollection<string> strings = new ObservableCollection<string> { “one”, “two”, “three” };

            return strings;

        }

    }

 

 

 

 

 

 

For the moment, I am going to skip over the ViewModel class as it is the most involved. Open up the View class and modify it to implement the IChildView interface. That brings in a method SetModel that will setup the data binding:

 

 

 

    public partial class ChildTwoView : UserControl, IChildTwoView

    {

        public ChildTwoView()

        {

            InitializeComponent();

        }

 

        public void SetModel(IChildTwoViewModel model)

        {

            DataContext = model;

        }

    }

 

 

 

 

 

 

Now open up the ChildTwoView.xaml file. Change the Grid layout panel to a StackPanel, and then add a ListBox to the StackPanel. Set the ItemsSource to the bind to the ModelStrings.

 

 

 

    <StackPanel>

        <Label Content=”Child two” />

        <ListBox ItemsSource=”{Binding ModelStrings}” />

    </StackPanel>

 

 

 

 

 

 

Now we come to the ViewModel class. The ViewModel class in the MVVM pattern takes on a lot of responsibility. The ViewModel not only provides data to the View but it also keeps track of the View state and acting as a go-between to the Model. One thing that is a really nifty feature is that the ViewModel can automatically update the Views data just by raising a property changed event. Okay so our ViewModel class needs to implement the IChildTwoViewModel interface and the INotifyPropertyChanged interface. The class constructor will need a reference to the View and the Model and set the ViewModel in the View:

 

 

 

        private readonly IChildTwoView _view;

        private readonly IChildTwoModel _model;

        private ObservableCollection<string> _modelStrings;

 

        public ChildTwoViewModel(IChildTwoView view, IChildTwoModel model)

        {

            _view = view;

            _model = model;

            _modelStrings = new ObservableCollection<string>();

            _modelStrings = _model.GetStrings();

            View.SetModel(this);

        }

 

 

 

 

 

 

 The SetModel method sets the data binding to the ViewModel. Now if you remember the View data binds the ListBox to something called ModelStrings so we need to implement a Property to expose the model strings:

 

 

 

        public ObservableCollection<string> ModelStrings

        {

            get

            {

                return _modelStrings;

            }

 

            set

            {

                _modelStrings = value;

                OnPropertyChanged(“ModelStrings”);

            }

        }

 

 

 

 

 

 

The OnPropertyChanged event notifies the View that the data has changed (if it does) and to update the data in the View.

 

        public event PropertyChangedEventHandler PropertyChanged;

 

        private void OnPropertyChanged(string propertyName)

        {

            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)

            {

                handler(this, new PropertyChangedEventArgs(propertyName));

            }

        }

 

The final thing is to modify the ChildTwoModule class to register the interfaces and the classes with the container just like we modified the ChildOneModule class.

 

 

 

        public void Initialize()

        {

            _container.RegisterType<IChildTwoModel, ChildTwoModel>();

            _container.RegisterType<IChildTwoViewModel, ChildTwoViewModel>();

            _container.RegisterType<IChildTwoView, ChildTwoView>();

 

            IChildTwoViewModel view = _container.Resolve<IChildTwoViewModel>();

 

            _regionManager.Regions[“RightChild”].Add(view.View);

        }

 

 

 

 

 

 

Now you should be able to compile and run that application and get a window similar to this:

 

final1

This concludes out whirlwind (and simplistic) tour of the Model-View-Presenter pattern and the Model-View-ViewModel in Prism. Hopefully you have a foundation from which to build and explore more in Prism. The final demonstration project (VS2008) can be found here. Rename the doc to zip before you open the archive. This is a wordpress.com requirment.

Advertisements

Comments»

1. Andy - July 11, 2009

Thank you for a very informative article, but I feel doubts about the MVVM example. I was convinced that in MVVM pattern the ViewModel does not reference the View (has no idea about the View). Rather View references ViewModel via DataContext, and any communication between those layers is handled by databinding.

wesaday - July 11, 2009

My personal opinion is that the View and the ViewModel should be seperate entities just as you said. However, the MVVM pattern does not forbid the VM from knowing about the view. There may be some circumstance that you would need that reference. So while you could do it, I certainly would not advocate making a habit of it. I guess I could have made that clearer.

Thanks for your comment.

2. Simon Brangwin - July 30, 2009

I also believe your interpretation of MVVM is not quite ideal.
There’s no need to reference the View from the ViewModel, so why do it. It introduces an unnecessary constraint that there can be only one View per view model instance.
The explicit View.SetModel(this) code in the ViewModel constructor is redundant. The view can retrieve the matching view model via dependency injection as the View knows of the IViewModel interface and can ask the IoC container (Unity in Prisms case) for one.
All other connections between the View and the View Model are handled by Silverlight/WPF binding and Commands, or Pub/Sub events in Prism. View state can be managed by the view itself. There’s absolutely no reason that I can see why the ViewModel would ever need to know about the view? For all it cares there could be any number of different of Views using it or none at all which is the elegance of this pattern IMHO.

wesaday - July 30, 2009

You are of course entitled to your opinion. I do not advocate referencing the view directly. If you examine the code I believe that you will find that the reference is to an interface not tied directly to a view. As long as a view implements the interface, there is no constraint and you can have multiple views using the same viewmodel.

wesaday - April 29, 2010

Thank you for your comment. I understood them completely. I think you missed my point entirely. First of all this is an example of MVVM in the confines of Prism. And second there is no reason whatsoever why the VM can not know about the existence of the View. And this is coming from the Patterns &Practices group. If you can point to a rule that says that the VM is absolutley not to know anything about the View than I will be more than happy to read up about it.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: