MVP Design Pattern For Windows Forms

This article describes the MVP design pattern for Windows Forms.

Introduction

MVP is a user interface architectural pattern engineered that follows the separation of concerns in the presentation logic. It is derived from the MVC design pattern. In MVC, all the presentation logic is moved to the presenter, hence make it suitable for automated unit testing. I will not go into the concept much since it is explained in many other places. Let us go with an example.

In the example, there are two views in the form, each with different colors.

Windows Form

Each view is extended from the IView interface as in the following:

  1. public interface IView  
  2.  {  
  3.      /// <summary>  
  4.      /// Load Data into controls  
  5.      /// </summary>  
  6.      void LoadView();  
  7.    
  8.      /// <summary>  
  9.      /// Load Data into controls  
  10.      /// </summary>  
  11.      bool Validate();  
  12.    
  13.      /// <summary>  
  14.      /// Presenter  
  15.      /// </summary>  
  16.      IPresenter Presenter { getset; }  
  17.    
  18.      /// <summary>  
  19.      /// Property changed notification  
  20.      /// </summary>  
  21.      /// <param name="propertyName"></param>  
  22.      void OnPropertyChanged(string propertyName);  
  23.  } 

 

Model Diagram

Corresponding to each view, there is a presenter and each presenter is driven from IPresenter as in the following:

  1. public interface IPresenter  
  2. {  
  3.     /// <summary>  
  4.     /// Load Data into presenter  
  5.     /// </summary>  
  6.     void LoadData(PersonModel personModel, PersonPresenter mainPresenter);  

 

Diagram View

The Model is defined as:

  1. public class PersonModel  
  2. {  
  3.     public string FirstName  
  4.     {  
  5.         get;  
  6.         set;  
  7.     }  
  8.     public string LastName  
  9.     {  
  10.         get;  
  11.         set;  
  12.     }  
  13.     public int Age  
  14.     {  
  15.         get;  
  16.         set;  
  17.     }  
  18.     public bool Married  
  19.     {  
  20.         get;  
  21.         set;  
  22.     }  
  23.     public string SpouseName  
  24.     {  
  25.         get;  
  26.         set;  
  27.     }  
  28.     public int Children  
  29.     {  
  30.         get;  
  31.         set;  
  32.     }  

There is a main presenter, which is exposed to the outer world and also defines the integration of Presenter and Views and put them in the form.

  1. public class PersonPresenter  
  2. {  
  3.     Dictionary<string, IView> _views;  
  4.     PersonForm _personForm;  
  5.   
  6.     public void LoadPersonUI(PersonModel person)  
  7.     {  
  8.         _personForm = new PersonForm();  
  9.         _views = new Dictionary<string, IView>();  
  10.   
  11.         DetailsView detailsView = new DetailsView();  
  12.         detailsView.Presenter = new DetailsPresenter();  
  13.   
  14.         _views.Add("Details", detailsView);  
  15.   
  16.         FamilyView familyView = new FamilyView();  
  17.         familyView.Presenter = new FamilyPresenter();  
  18.   
  19.         _views.Add("Family", familyView);  
  20.   
  21.         foreach (string key in this._views.Keys)  
  22.         {  
  23.             Control viewControl = this._views[key] as Control;  
  24.             viewControl.Dock = DockStyle.Left;  
  25.             _personForm.Controls.Add(viewControl);  
  26.             viewControl.BringToFront();  
  27.         }  
  28.   
  29.         foreach (string key in this._views.Keys)  
  30.         {  
  31.             _views[key].Presenter.LoadData(person, this);  
  32.             _views[key].LoadView();  
  33.         }  
  34.   
  35.         _personForm.Show();  
  36.     }  
  37.   
  38.     internal bool Validate()  
  39.     {  
  40.         foreach (string key in this._views.Keys)  
  41.         {  
  42.             if (!_views[key].Validate())  
  43.                 return false;  
  44.         }  
  45.         return true;  
  46.     }  
  47.   
  48.     internal void NotifyViewPropertyChanged(string propertyName)  
  49.     {  
  50.             foreach (IView view in _views.Values)  
  51.             view.OnPropertyChanged(propertyName);  
  52.     }  

 

This presenter is called from the outside world like this:

  1. PersonPresenter personPresenter = new PersonPresenter();  
  2. personPresenter.LoadPersonUI(new PersonModel()); 

the code is attached here with this example, if something is not clear then please let me know.