winforms中的MVP模式 - 处理事件

时间:2014-04-16 01:49:25

标签: c# winforms design-patterns mvp

我刚开始使用C#和MVP设计模式。 在事件处理方面,我对具体实现有疑问。我知道,视图不应该知道演示者和演示者应该通过视图界面控制视图。

假设我有2个文本框,并希望检查错误。如果发生错误,我想更改文本框Text属性。创建一个EventHandler并使用sender对象来验证用户当前正在使用的文本框是错误的方法吗?

类似的东西:

IVIEW:

interface IMainView
{
    event KeyPressEventHandler KeyPressed;
}

查看:

public partial class MainView : Form, IMainView
{
    public frmInterakcija()
    {
        InitializeComponent();
        this.textBox1.Name = "textBox1";
        this.textBox2.Name = "textBox2";
        new MainPresenter();
        Bind();
    }

    private void Bind()
    {

       this.textBox1.KeyPress += KeyPressed;
       this.textBox2.KeyPress += KeyPressed;
    }
}

主讲人:

class MainPresenter
{
    private IMainView _view;

    public MainPresenter(IMainView view) 
    {
        _view = view;
        this.initialize();

    }

    public void initialize()
    {
        _view.KeyPressed += _view_textBoxKeyPressed;
    }

    public void _view_textBoxKeyPressed(object sender, EventArgs e)
    {
        if (sender.GetType() == typeof(TextBox))
        {
            TextBox textBox = (TextBox)sender;
            if (textBox.Name.Equals("textbox1") 
                {...} // Do validation/changes on textbox1
            else ...

        }
    }
 }

或者不是上面这个我应该为我拥有的每个文本框创建事件处理程序并通过属性更新/处理错误? (这会使我的代码变得多余)

什么是正确的方法?

2 个答案:

答案 0 :(得分:2)

恕我直言,presenter应该不知道查看特定对象(代码中的示例textbox)。这种逻辑不应该在主持人中。并且演示者必须不知道UI中的控件ID,这更糟糕。请记住,这样做的一个好处应该是您可以通过模拟视图来测试演示者,如果您有特定于UI的代码,则无法对演示者进行单元测试。

对我来说,似乎有两种不同的events,因为你做的是不同的逻辑。我会提出两个不同的events,一个会做验证,另一个会做自己的逻辑。演示者无需检查发件人是textbox还是textbox的ID。另外,如果您有另一个文本框,那么在当前实现中您将需要另一个if条件。

此外,在视图中,它应该是new MainPresenter(this);

答案 1 :(得分:2)

您的演示者绝对不应该在其中包含特定于视图的类型(例如控件,事件等),因为在测试演示者的逻辑时,这些类型很难伪造。相反,你应该有类似的东西。

IVIEW:

interface IMainView
{
    // give these better names based on what they actually represent (e.g. FirstName and LastName)
    // you could also add setters if you needed to modify their values from the presenter
    string Text1 { get; } 
    string Text2 { get; }

    // provide a way to bubble up validation errors to the UI
    string ErrorMessage { get; set; }
}

主讲人:

class MainPresenter
{
    private IMainView _view;

    public MainPresenter(IMainView view) 
    {
        _view = view;
    }

    public void ValidateText1()
    {
        if (/* some validation is false */)
        {
            _view.ErrorMessage = "Text1 isn't valid";
        }
    }

    public void ValidateText2()
    {
        if (/* some validation is false */)
        {
            _view.ErrorMessage = "Text2 isn't valid";
        }
    }
 }

查看:

public partial class MainView : Form, IMainView
{
    var readonly MainPresenter _presenter;

    public frmInterakcija()
    {
        InitializeComponent();
        _presenter = new MainPresenter(this);
    }

    private void textBox1_KeyPress(object sender, KeyPressEventArgs eventArgs)
    {
        _presenter.ValidateText1();
    }

    private void textBox2_KeyPress(object sender, KeyPressEventArgs eventArgs)
    {
        _presenter.ValidateText2();
    }

    #region Implementation of IMainView

    public string Text1
    {
        get { return textBox1.Text; }
    }

    public string Text2
    {
        get { return textBox2.Text; }
    }

    public string ErrorMessage
    {
        get { return labelErrorMessage.Text; }
        set { labelErrorMessage.Text = value; }
    }

    #endregion
}