【发布时间】:2019-11-28 08:09:29
【问题描述】:
我正在做一个项目,我实际上在使用具有一些自动化行为的继承控件,因此我不需要重新完成所有工作。控件是从 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 完成吗?
【问题讨论】:
-
BinaryGridView_InvalidRowException只是订阅事件,然后您可以将grwWhatever.InvalidRowException分配给null。在这种情况下,无需将访问器类型更改为public。 -
如果
NoAction的值为ExceptionMode,因为你总是意味着不显示消息框,那么只需转到继承控件并在消息框之前添加 if 语句:if (e.ExceptionMode==ExceptionMode.NoAction). -
同样在inherited control中,如果可能的话,最好覆盖
OnInvalidRowException进行扩展,而不是有一个事件处理程序。 -
如果
BinaryGridView_InvalidRowException是订阅了继承控件中的事件的事件处理程序,并且您无法更改继承的控件代码,则无法阻止它工作。 -
是的,有使用反射的解决方案。我将使用
Form类及其Load事件发布一个示例。
标签: c# .net winforms event-handling