简体   繁体   English

如何在MVP中将EventArgs从View传递到Presenter?

[英]How to pass EventArgs from View to Presenter in MVP?

I have an application based on MVP, WinForms and EntityFramework. 我有一个基于MVP,WinForms和EntityFramework的应用程序。 At one form I need to validate cell value, but I don't know proper way to pass EventArgs from Validating event of DataGridView to my presenter. 在一种形式下,我需要验证单元格值,但是我不知道将EventArgs从DataGridView的Validating事件传递给演示者的正确方法。

I have this Form (unrelated code omitted): 我有这个表格(省略了不相关的代码):

public partial class ChargeLinePropertiesForm : Form, IChargeLinePropertiesView
{
    public event Action CellValidating;

    public ChargeLinePropertiesForm()
    {
        InitializeComponent();
        dgBudget.CellValidating += (send, args) => Invoke(CellValidating);
    }

    private void Invoke(Action action)
    {
        if (action != null) action();
    }

    public DataGridView BudgetDataGrid
    {
        get { return dgBudget; }
    }
}

Interface: 接口:

public interface IChargeLinePropertiesView:IView
{
    event Action CellValidating;
    DataGridView BudgetDataGrid { get; }
}

And this presenter: 这位主持人:

public class ChargeLinePropertiesPresenter : BasePresenter<IChargeLinePropertiesView, ArgumentClass>
{
    public ChargeLinePropertiesPresenter(IApplicationController controller, IChargeLinePropertiesView view)
        : base(controller, view)
    {
        View.CellValidating += View_CellValidating;
    }

    void View_CellValidating()
    {
        //I need to validate cell here based on dgBudget.CellValidating EventArgs
        //but how to pass it here from View?

        //typeof(e) == DataGridViewCellValidatingEventArgs
        //pseudoCode mode on
        if (e.FormattedValue.ToString() == "Bad")
        {
            View.BudgetDataGrid.Rows[e.RowIndex].ErrorText =
                "Bad Value";
            e.Cancel = true;
        }
        //pseudoCode mode off
    }
}

Yes, I could expose a property through interface and set my EventArgs to this property in View to get them from Presenter, but this is ugly, isn't it? 是的,我可以通过接口公开一个属性,然后在View中将该EventArgs设置为该属性,以从Presenter获取它们,但这很丑陋,不是吗?

public interface IChargeLinePropertiesView:IView
{
    event Action CellValidating;
    // etc..
}

Using Action is the problem here, it is the wrong delegate type. 使用Action是这里的问题,它是错误的委托类型。 It doesn't permit passing any arguments. 它不允许传递任何参数。 More than one way to solve this problem, you could use Action<CancelEventArgs> for example. 解决此问题的方法不止一种,例如,可以使用Action<CancelEventArgs> But the logical choice is to use the same delegate type that the Validating event uses: 但是逻辑选择是使用与Validating事件使用的委托类型相同的委托类型:

event CancelEventHandler CellValidating;

Now it is easy. 现在很容易。 In your form: 以您的形式:

public event CancelEventHandler CellValidating;

public ChargeLinePropertiesForm() {
    InitializeComponent();
    dgBudget.CellValidating += (sender, cea) => {
        var handler = CellValidating;
        if (handler != null) handler(sender, cea);
    };
}

In your presenter: 在您的演示者中:

void View_CellValidating(object sender, CancelEventArgs e)
{
   //...
   if (nothappy) e.Cancel = true;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM