C# 如何覆盖继承的控件';在没有访问权限的情况下发生的事件?
我正在做一个项目,在这个项目中,我实际上使用了一些自动行为的继承控件,所以我不需要重新做所有的工作。这些控件是从DevExpress控件继承的,我可以访问继承的控件 我到达了一个触发事件的点,订阅我自己的方法没有显示任何结果,因为继承的控件执行它自己的代码 继承控制:C# 如何覆盖继承的控件';在没有访问权限的情况下发生的事件?,c#,.net,winforms,event-handling,C#,.net,Winforms,Event Handling,我正在做一个项目,在这个项目中,我实际上使用了一些自动行为的继承控件,所以我不需要重新做所有的工作。这些控件是从DevExpress控件继承的,我可以访问继承的控件 我到达了一个触发事件的点,订阅我自己的方法没有显示任何结果,因为继承的控件执行它自己的代码 继承控制: private void BinaryGridView_InvalidRowException(object sender, InvalidRowExceptionEventArgs e) { e.ExceptionMod
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; };
根据,我试图隐藏任何消息框,当然,正如我继承的控制源所说,它正在显示该消息框
因此,我想达到这一点有两种选择:
1.-从继承的控件继承,将private
更改为protected virtual
并重写该行为。这不是一个选择,因为,出于我无法在此解释的原因,我必须唯一地使用那些继承的控件
2.-将private
更改为public
,以便我可以取消订阅并再次订阅,之后:
grwWhatever.InvalidRowException -= grwWhatever.BinaryGridView_InvalidRowException;
grwWhatever.InvalidRowException += (s, e) => { e.ExceptionMode = ExceptionMode.NoAction; };
第二个选项实际上运行良好,但是。。。让我们猜猜它们都不可行。无法更改继承控件事件的内容。将部分保留为继承控件的使用设计哪种方法是最好的继续进行?是否可以使用
反射?正确的解决方案应该是更改基类中的代码。但是,既然您已经提到,您无法更改基类的代码,而且使用反射的解决方案也是可以接受的,那么为了学习的目的,我将在这里分享一个使用反射的示例
从基类中删除私有事件处理程序订阅
我假设我有一个名为MyBaseForm
的基类,并且您已经在基类中使用MyBaseForm\u Load
私有方法处理了Load
事件
在本例中,在从基类派生的派生类MyDerivedForm
中,我使用一些反射代码删除MyBaseForm\u Load
事件订阅,而是使用派生类MyDerivedForm\u Load
中的新处理程序处理事件
预期行为:
- 在删除事件处理程序之前,您将看到两个消息框
- 使用
eventInfo.RemoveEventHandler
删除事件处理程序后,您将只看到派生类事件处理程序中的一个消息框
代码如下:
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");
}
}
BinaryGridView\u InvalidRowException
是唯一订阅的事件,然后您可以将grwWhatever.InvalidRowException
分配给null
。在这种情况下,无需将访问器类型更改为public
。如果ExceptionMode
的NoAction
值,因为您总是意味着不显示消息框,那么只需转到继承的控件并在消息框之前添加if语句:if(e.ExceptionMode==ExceptionMode.NoAction)
。在继承的控件中,如果可能,最好将OnInvalidRoweException
重写为扩展,而不是使用事件处理程序。如果BinaryGridView\u InvalidRoweException
是订阅到继承控件中的事件的事件处理程序,则无法更改继承的控件代码,然后你不能阻止它工作。是的,有一个解决方案是使用反射。我将发布一个使用Form
类及其Load
事件的示例。就是这样!我可以选择在继承的控件中更改代码,因为我有源代码,但我很好奇在一个不可能的场景中如何做到这一点。这太棒了。如果您可以更改基类代码,那么最好按照我在问题下面发布的注释进行操作:)