【问题标题】:How to remove Closing event?如何删除关闭事件?
【发布时间】:2017-06-12 21:46:04
【问题描述】:

我找到了一个很好的例子,说明如何从表单中删除所有 Click 事件:

private void RemoveClickEvent(Form c)
{
    var f1 = typeof(Control).GetField("EventClick", BindingFlags.Static | BindingFlags.NonPublic);
    var obj = f1.GetValue(c);
    var pi = c.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
    var list = (EventHandlerList)pi.GetValue(c, null);
    list.RemoveHandler(obj, list[obj]);
}

而且效果很好。但是,我需要删除 Closing 事件,但我不知道要写什么而不是 EventClick 以使其工作。我试着写EventClosingClosing,但是没有用。因此我的问题是:应该进行哪些更改才能使其正常工作?更好 - 我想在那里找到所有可能输入的列表,因为我可能需要删除其他输入ClosedFormClosingFormClosed 等事件。

附:一个简单的-= 是不可能的,因为可能有许多附加的事件,其中许多我根本无法访问,因此我无论如何都无法删除它们。

【问题讨论】:

  • 你想要强制表单不关闭吗?
  • 不,实际上恰恰相反——我想在不触发任何事件的情况下关闭它,除了标准关闭。例如:我想阻止表单显示询问“有未保存的更改。您确定要关闭吗?”的 MessageBox。
  • 所以当您单击或尝试关闭表单时,它会显示带有问题的消息框?我无法完全理解您的问题,但您不能删除显示消息框的代码吗?
  • 是的,这是正确的 - 它显示一个对话框。除了创建 var form = new MyForm(); form.ShowDialog(); 之外,我无法控制表单。然后我想用form.Close(); 关闭它,但是对话框阻止代码继续,因此我想摆脱它。我正在对数百个这样的表格进行测试,我只想看看它们是否成功打开。也许还有另一种关闭对话框本身的方法,但我试图找出带有对话框和没有对话框的表单之间的区别——唯一的区别是 CanFocus 属性的值。
  • 我似乎找到了用typeof(Form).GetFields(BindingFlags.NonPublic | BindingFlags.Static).AsEnumerable().ToList()显示事件列表的解决方案

标签: c# winforms events event-handling formclosing


【解决方案1】:

正如 cmets 中提到的,我列出了这些事件名称:

typeof(Form).GetFields(BindingFlags.NonPublic | BindingFlags.Static).AsEnumerable().ToList();

现在我有一个看起来像这样的方法:

public static class Utils
{
    public static void DisableEvents<T>(this T ctrl, string officialName, string simplifiedName) where T : Control
    {
        var propertyInfo = ctrl.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
        var eventHandlerList = propertyInfo.GetValue(ctrl, new object[] { }) as EventHandlerList;
        var fieldInfo = typeof(T).GetField(officialName, BindingFlags.NonPublic | BindingFlags.Static);
        var eventKey = fieldInfo.GetValue(ctrl);
        var eventHandler = eventHandlerList[eventKey];
        var invocationList = eventHandler.GetInvocationList();

        foreach (var item in invocationList)
        {
            ctrl.GetType().GetEvent(simplifiedName).RemoveEventHandler(ctrl, item);
        }
    }
}

而且用法是这样的:

myForm.DisableEvents<Form>("EVENT_CLOSING", "Closing");

不幸的是,我还没有想出一种将单个参数传递给我的方法的方法。

【讨论】:

    【解决方案2】:

    根据之前的帖子,用法应该是这样的:

            myForm.DisableEvents<Form>("EVENT_FORMCLOSING", "FormClosing");
            myForm.DisableEvents<Form>("EVENT_FORMCLOSED", "FormClosed");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-27
      • 1970-01-01
      相关资源
      最近更新 更多