.

Simple MVP in Winforms

Here follows a very simple MVP sample application as prototype for larger implementations:
Download Code: simple MVC example code

The UML:
20-02-2013 14-00-33

Model:

public interface IModel : INotifyPropertyChanged
{
    string Name { get; set; }
    string Email { get; set; }
}

public class Model : IModel
{
    private string email;
    private string name;

    #region IModel Members

    public event PropertyChangedEventHandler PropertyChanged;

    public string Name
    {
        get { return name; }
        set
        {
            if (name == value)
                return;
            name = value;
            Fire("Name");
        }
    }

    public string Email
    {
        get { return email; }
        set
        {
            if (email == value)
                return;
            email = value;
            Fire("Email");
        }
    }

    #endregion

    private void Fire(string propertyName)
    {
        if (null != PropertyChanged)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

IView:

public interface IView : INotifyPropertyChanged
    //: IModel - if it is a one to one mapping
{
    string Name { get; set; }
    string Email { get; set; }
    event EventHandler SubmitButtonClicked;
}

Presenter:

public class Presenter
{
    private readonly IModel model;
    private readonly IView view;

    public Presenter(IView view, IModel model)
    {
        this.view = view;
        this.model = model;

        view.PropertyChanged += view_onchange;
        view.SubmitButtonClicked +=
            (sender, args) => { MessageBox.Show(
            string.Format("click {0} {1}", model.Name, model.Email)); };
        model.PropertyChanged += model_PropertyChanged;
    }

    private void model_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        updateViewWithModel();
    }

    private void updateViewWithModel()
    {
        view.Name = model.Name;
        view.Email = model.Email;
    }

    private void view_onchange(object sender, EventArgs e)
    {
        updateModelwithView();
    }

    private void updateModelwithView()
    {
        model.Name = view.Name;
        model.Email = view.Email;
    }
}

an actual concrete implementation of IView:

public partial class edituserform : Form, IView
{

    private System.Windows.Forms.Label label1;
    private System.Windows.Forms.Label label2;
    private System.Windows.Forms.TextBox textBox1;
    private System.Windows.Forms.TextBox textBox2;
    private System.Windows.Forms.Button button1;

    public edituserform()
    {
        this.label1 = new System.Windows.Forms.Label();
        this.label2 = new System.Windows.Forms.Label();
        this.textBox1 = new System.Windows.Forms.TextBox();
        this.textBox2 = new System.Windows.Forms.TextBox();
        this.button1 = new System.Windows.Forms.Button();
        this.SuspendLayout();
        // 
        // label1
        // 
        this.label1.AutoSize = true;
        this.label1.Location = new System.Drawing.Point(52, 40);
        this.label1.Name = "label1";
        this.label1.Size = new System.Drawing.Size(35, 13);
        this.label1.TabIndex = 0;
        this.label1.Text = "Name";
        // 
        // label2
        // 
        this.label2.AutoSize = true;
        this.label2.Location = new System.Drawing.Point(52, 98);
        this.label2.Name = "label2";
        this.label2.Size = new System.Drawing.Size(32, 13);
        this.label2.TabIndex = 1;
        this.label2.Text = "Email";
        // 
        // textBox1
        // 
        this.textBox1.Location = new System.Drawing.Point(94, 32);
        this.textBox1.Name = "textBox1";
        this.textBox1.Size = new System.Drawing.Size(100, 20);
        this.textBox1.TabIndex = 2;
        this.textBox1.TextChanged += 
                new System.EventHandler(this.textBoxName_TextChanged);
        // 
        // textBox2
        // 
        this.textBox2.Location = new System.Drawing.Point(94, 98);
        this.textBox2.Name = "textBox2";
        this.textBox2.Size = new System.Drawing.Size(100, 20);
        this.textBox2.TabIndex = 3;
        this.textBox2.TextChanged += 
                new System.EventHandler(this.textBoxEmail_TextChanged);
        // 
        // button1
        // 
        this.button1.Location = new System.Drawing.Point(108, 224);
        this.button1.Name = "button1";
        this.button1.Size = new System.Drawing.Size(75, 23);
        this.button1.TabIndex = 4;
        this.button1.Text = "button1";
        this.button1.UseVisualStyleBackColor = true;
        this.button1.Click += new EventHandler(button1_Click);
        // 
        // edituserform
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(284, 262);
        this.Controls.Add(this.button1);
        this.Controls.Add(this.textBox2);
        this.Controls.Add(this.textBox1);
        this.Controls.Add(this.label2);
        this.Controls.Add(this.label1);
        //this.Name = "edituserform";
        this.Text = "edituserform";
        this.ResumeLayout(false);
        this.PerformLayout();

    }

    void button1_Click(object sender, EventArgs e)
    {
        if (SubmitButtonClicked != null)
            SubmitButtonClicked(this, e);
    }

    #region IView Members

    public string Name
    {
        get
        {
            return textBox1.Text;
        }
        set
        {
            if (textBox1.Text == value)
                return;
            textBox1.Text = value;
        }
    }

    public string Email
    {
        get
        {
            return textBox2.Text;
        }
        set
        {
            if (textBox2.Text == value)
                return;
            textBox2.Text = value;
        }
    }

    public event EventHandler SubmitButtonClicked;

    #endregion

    private void textBoxName_TextChanged(object sender, EventArgs e)
    {
        if (null != PropertyChanged)
            PropertyChanged(this, new PropertyChangedEventArgs("Name"));
    }

    private void textBoxEmail_TextChanged(object sender, EventArgs e)
    {
        if (null != PropertyChanged)
            PropertyChanged(this, new PropertyChangedEventArgs("Email"));
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

}

And the code that hooks it all up:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        IModel model = new Model();
        IView mainForm = new edituserform();
        var p = new Presenter(mainForm, model);

        Application.Run((Form)mainForm);
    }
}

Download Code: simple MVC example code

2 Responses to this post.

  1. Posted by std on 20.02.13 at 1:35 pm

    Thx for detailed description

  2. Posted by Tuan Le Minh on 20.02.13 at 1:35 pm

    Thank for sample ;)

What's your thoughts on this?

*

Protected by WP Anti Spam