1

1 つの TextBox (CustomerName) と 2 つのボタン (保存/キャンセル) を持つ単純な UserControl を想像してください。

この UserControl は、さらに 2 つのボタン (PreviousCustomer/NextCustomer) を持つ親コントロール内にあります。

問題は、モデルをプレゼンターに渡す場所がわからないことです。ビューコンストラクターを使用しますか? モデルが変更された場合 (PreviousCustomer/NextCustomer がクリックされた場合) はどうなりますか? 毎回新しいビューを作成しますか? UserControl が多くの子を持つ複雑な場合、これは無駄に思えます。ビューとプレゼンターに UpdateModel メソッドを実装できますか?それとも正しくありませんか?

これが私のコードです:

public interface IModel
{
    string CustomerName { get; set; }
}

public class Presenter
{
    private IView _view;
    private IModel _model;

    public Presenter(IView view, IModel model)
    {
        _view = view;
        _model = model;
        _view.CustomerName = _model.CustomerName;
    }

    public void Save()
    {
        _model.CustomerName = _view.CustomerName;
    }

    public void Cancel()
    {
        _view.CustomerName = _model.CustomerName;
    }

    public void UpdateModel(IModel newModel)
    {
        _model = newModel;
        _view.CustomerName = _model.CustomerName;
    }
}

public interface IView
{
    string CustomerName { get; set; }
}

public class View : UserControl, IView
{
    private Presenter _presenter;

    public string CustomerName
    {
        get { return CustomerNameEditBox.Text; }
        set { CustomerNameEditBox.Text = value; }
    }

    //Is this the right place to pass in the model?
    public View(IModel model)
    {
        _presenter = new Presenter(this, model);
    }

    private void SaveButton_Click(object sender, EventArgs e)
    {
        _presenter.Save();
    }

    private void CancelButton_Click(object sender, EventArgs e)
    {
        _presenter.Cancel();
    }

    public void UpdateModel(IModel newModel)
    {
        _presenter.UpdateModel(newModel);
    }
}

編集:以下のコメントで述べたように、私はビューを完全に馬鹿にして、プレゼンターやモデルについて何も知らないことが最善だと思います。これが私の修正されたコードです。

モデル:

public interface IModel
{
    string CustomerName { get; set; }
}

public class Model : IModel
{
    public string CustomerName { get; set; }

    public Model(string name)
    {
        CustomerName = name;
    }
}

意見:

public interface IView
{
    event EventHandler SaveClick;
    event EventHandler CancelClick;
    string CustomerName { get; set; }
}

public class View : UserControl, IView
{
    public event EventHandler SaveClick
    {
        add { SaveButton.Click += value; }
        remove { SaveButton.Click -= value; }
    }

    public event EventHandler CancelClick
    {
        add { CancelButton.Click += value; }
        remove { CancelButton.Click -= value; }
    }

    public string CustomerName
    {
        get { return CustomerNameEditBox.Text; }
        set { CustomerNameEditBox.Text = value; }
    }
}

プレゼンター:

public class Presenter
{
    private IView _view;
    private IModel _model;

    public Control View
    {
        get { return (Control)_view; } 
    }

    public Presenter(IView view, IModel model)
    {
        _view = view;
        _view.SaveClick += new EventHandler(_view_SaveClick);
        _view.CancelClick += new EventHandler(_view_CancelClick);
        _model = model;
        _view.CustomerName = _model.CustomerName;
    }

    void _view_SaveClick(object sender, EventArgs e)
    {
        _model.CustomerName = _view.CustomerName;
    }

    void _view_CancelClick(object sender, EventArgs e)
    {
        _view.CustomerName = _model.CustomerName;
    }

    public void ChangeModel(IModel newModel)
    {
        _model = newModel;
        _view.CustomerName = _model.CustomerName;
    }
}

使用法:

public class MainProgram : Form
{
    public void ArbitraryMethod()
    {
        //Create a new model object
        IModel model1 = new Model("test1");

        //Create the presenter with the model and any view implementing IView
        Presenter presenter = new Presenter(new View(), model1);

        //Add the view to a panel control in this form
        mainPanel.Controls.Add(presenter.View);

        //Change the model
        IModel model2 = new Model("test2");
        presenter.ChangeModel(model2);
    }
}
4

1 に答える 1