如何在没有访问权限的情况下覆盖继承控件的事件?

问题描述 投票:0回答:1

我正在一个项目中,我实际上正在使用具有某些自动行为的继承控件,因此我不需要重新做所有工作。这些控件是从DevExpress控件继承的,我可以访问这些继承的控件。

我到达了一个引发事件并且订阅我自己的方法的结果,因为继承的控件执行了自己的代码,因此未显示任何结果。

继承的控件:

private void BinaryGridView_InvalidRowException(object sender, InvalidRowExceptionEventArgs e)
{
    e.ExceptionMode = DevExpress.XtraEditors.Controls.ExceptionMode.NoAction;
    DevExpress.XtraEditors.XtraMessageBox.Show(e.ErrorText, "Atención", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

我的表单中的自己的方法:

grwWhatever.InvalidRowException += (s, e) => { e.ExceptionMode = ExceptionMode.NoAction; };

根据documentation,我试图隐藏任何消息框,当然,正如我继承的控制源所说,它正在显示该消息框。

所以,达到这一点我想有两个选择:

1.-从该继承控件继承,将private更改为protected virtual并覆盖该行为。这不是一个选择,因为出于某种原因,我无法在此处解释我必须唯一地使用那些继承的控件

2.-将private更改为public,这样我以后可以取消订阅并再次订阅:

grwWhatever.InvalidRowException -= grwWhatever.BinaryGridView_InvalidRowException;
grwWhatever.InvalidRowException += (s, e) => { e.ExceptionMode = ExceptionMode.NoAction; };

此第二个选项实际上工作正常,但是...让我们猜测它们都不可行。更改继承控件事件的内容是不可能的。留下继承的控件的用法设计的一部分... 哪种是最好的处理方法?可以使用Reflection完成吗?

c# winforms event-handling
1个回答
0
投票

正确的解决方案应该是更改基类中的代码。但是,由于您已经提到了您无权更改基类的代码,并且使用反射的解决方案也是可以接受的,因此在这里,我将分享一个使用反射的示例。

从基类中删除事件处理程序订阅

[我假设我有一个名为MyBaseForm的基类,并且您已经在基类中使用Load私有方法处理了MyBaseForm_Load事件。

在此示例中,在派生自基类的派生类MyDerivedForm中,我使用一些反射代码来删除MyBaseForm_Load事件订阅,而是使用派生类MyDerivedForm_Load中的新处理程序来处理事件]:

public class MyBaseForm : Form
{
    public MyBaseForm()
    {
        this.Load += MyBaseForm_Load;
    }
    private void MyBaseForm_Load(object sender, EventArgs e)
    {
        MessageBox.Show("MyBaseForm_Load");
    }
}

public class MyDerivedForm : MyBaseForm
{
    public MyDerivedForm()
    {
        var eventInfo = this.GetType().GetEvent("Load",
            System.Reflection.BindingFlags.Public |
            System.Reflection.BindingFlags.Instance);
        var delegateType = eventInfo.EventHandlerType;
        eventInfo.RemoveEventHandler(this, 
            Delegate.CreateDelegate(delegateType, this, "MyBaseForm_Load", false, true));

        this.Load += MyDerivedForm_Load;
    }

    private void MyDerivedForm_Load(object sender, EventArgs e)
    {
        MessageBox.Show("MyDerivedForm_Load");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.