8
\$\begingroup\$

First of all, I'm really new to the MVP design pattern (Passive-View) and I've been trying to implement it in a WinForms application.

Before I'm going any further, I'd be very happy if you guys can give me feedback on my current work.

Solution Explorer structure

The Form

Model:

public class PersonModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Gender { get; set; }

    public PersonModel(string firstName, string lastName, string gender)
    {
        FirstName = firstName;
        LastName = lastName;
        Gender = gender;
    }
}

Presenter:

public class ManagePersonPresenter
{
    private readonly IManagePersonFormView _view;
    private readonly List<PersonModel> _models;

    public ManagePersonPresenter(IManagePersonFormView view)
    {
        _view = view;
        _models = new List<PersonModel>();

        Initialize();
    }

    private void Initialize()
    {
        _view.AddButtonEnabled = false;
        _view.InputGenderMale = true;
    }

    public void OnSaveButtonClicked()
    {
        var person = new PersonModel(_view.InputFirstName, _view.InputLastName, GetGender());

        _view.AddButtonEnabled = false;
        _view.InputFirstName = null;
        _view.InputLastName = null;

        _models.Add(person);

        _view.ShowMessage("Successfully added person '" + person.FirstName + @"'.");

        RefreshTable();
    }

    public void OnTextChanged()
    {
        if (_view.InputFirstName == string.Empty || _view.InputLastName == string.Empty)
        {
            _view.AddButtonEnabled = false;
        }
        else
        {
            _view.AddButtonEnabled = true;
        }
    }

    public void RefreshTable()
    {
        var dt = new DataTable();
        dt.Columns.Add("First name");
        dt.Columns.Add("Last name");
        dt.Columns.Add("Gender");

        foreach (var person in _models)
        {
            dt.Rows.Add(person.FirstName, person.LastName, person.Gender);
        }

        _view.DtPersons = dt;
    }

    private string GetGender()
    {
        return _view.InputGenderMale ? "Male" : "Female";
    }
}

View:

public interface IManagePersonFormView
{
    string InputFirstName { get; set; }
    string InputLastName { get; set; }
    bool InputGenderMale { get; set;  }
    bool InputGenderFemale { get; set; }
    DataTable DtPersons { set; }
    bool AddButtonEnabled { get; set; }
    void ShowMessage(string message);
}

The Form:

public partial class FrmManagePersons : Form, IManagePersonFormView
{
    private readonly ManagePersonPresenter _presenter;

    public FrmManagePersons()
    {
        InitializeComponent();

        _presenter = new ManagePersonPresenter(this);
    }

    public string InputFirstName
    {
        get => txtBoxFirstName.Text;
        set => txtBoxFirstName.Text = value;
    }

    public string InputLastName
    {
        get => txtBoxLastName.Text;
        set => txtBoxLastName.Text = value;
    }

    public bool AddButtonEnabled
    {
        get => btnSavePerson.Enabled;
        set => btnSavePerson.Enabled = value;
    }

    public bool InputGenderMale
    {
        get => rdBtnGenderMale.Checked;
        set => rdBtnGenderMale.Checked = value;
    }

    public bool InputGenderFemale
    {
        get => rdBtnGenderFemale.Checked;
        set => rdBtnGenderFemale.Checked = value;
    }

    public DataTable DtPersons
    {
        set => dtGridPersons.DataSource = value;
    }

    public void ShowMessage(string message)
    {
        MessageBox.Show(message, @"Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }

    private void btnSavePerson_Click(object sender, EventArgs e)
    {
        _presenter.OnSaveButtonClicked();
    }

    private void txtBoxFirstName_TextChanged(object sender, EventArgs e)
    {
        _presenter.OnTextChanged();
    }

    private void txtBoxLastName_TextChanged(object sender, EventArgs e)
    {
        _presenter.OnTextChanged();
    }

    private void dtGridPersons_SelectionChanged(object sender, EventArgs e)
    {
        dtGridPersons.ClearSelection();
    }

    private void btnRefreshTable_Click(object sender, EventArgs e)
    {
        _presenter.RefreshTable();
    }
}
\$\endgroup\$
6
\$\begingroup\$

Your view is calling methods on your presenter. The view shouldn’t know the presenter exists. Instead of calling the presenter directly, the view should raise events that the presenter reacts to. The difference seems trivial for what you have here, but it can make quite a large difference on a larger more complex system.

Oh, and I should mention a few other things.

  1. Gender isn’t a binary option.
  2. Names are far more complicated than First & Last.
\$\endgroup\$
  • \$\begingroup\$ Thank you for your answer! Btw. this is just a test project :-) \$\endgroup\$ – Danivin Apr 1 '18 at 12:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.