Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 确定绑定到事件的事件处理程序列表_C#_Visual Studio 2008_Debugging_Events - Fatal编程技术网

C# 确定绑定到事件的事件处理程序列表

C# 确定绑定到事件的事件处理程序列表,c#,visual-studio-2008,debugging,events,C#,Visual Studio 2008,Debugging,Events,我有一个WinForms表单无法关闭。在OnFormClosing中,e.Cancel设置为true。我猜我的应用程序中的某个对象已绑定到Closing或FormClosing事件,并且正在阻止关闭。为了找出答案,我想确定哪些代理绑定到这些事件之一 有没有办法确定绑定到事件的处理程序列表?理想情况下,我会通过VisualStudio调试器执行此操作,但如果需要,可以在应用程序中编写代码以查找处理程序。了解到事件就像一个隐藏的私有字段,我已通过调试器导航到窗体的“Windows.Forms.For

我有一个WinForms表单无法关闭。在OnFormClosing中,e.Cancel设置为true。我猜我的应用程序中的某个对象已绑定到Closing或FormClosing事件,并且正在阻止关闭。为了找出答案,我想确定哪些代理绑定到这些事件之一


有没有办法确定绑定到事件的处理程序列表?理想情况下,我会通过VisualStudio调试器执行此操作,但如果需要,可以在应用程序中编写代码以查找处理程序。了解到事件就像一个隐藏的私有字段,我已通过调试器导航到窗体的“Windows.Forms.Form”祖先的“非公共字段”,但没有任何效果。

简而言之,您不打算这样做-但出于调试目的

事件通常由私人字段支持,但没有控件;他们使用
EventHandlerList
方法。您必须访问表单的受保护的
事件
成员,查找映射到(private)EVENT\u FORMCLOSING对象的对象

一旦有了
表单closingeventhandler
GetInvocationList
就应该完成这项工作



问题可能是表单无法验证

FormClosing
事件由
Form
中的私有
WmClose
方法引发,该方法将
e.Cancel
初始化为
!验证(真)
。我还没有调查过,但在某些情况下,
Validate
将始终返回
false
,从而导致关闭被取消,而不考虑任何事件处理程序

要对此进行调查,请启用,在
FormClosing
处理程序中放置一个断点,转到
Form.WmClose
的源代码(向上调用堆栈),在
WmClose
的开头放置一个断点,然后再次关闭表单。然后,在调试器中逐步检查它,并查看为什么
Validate
返回
false
。(或者哪个事件处理程序正在将
e.Cancel
设置为true)


要解决此问题,请在您自己的处理程序中将
e.Cancel
设置为
false

Coolness。谢谢你的快速回复,马克!我也有同样的需要;在
Control
中,识别键的命名方式类似于
EventMouseDown
而不是
EVENT\u MOUSEDOWN
,因为它们是用于
Form
的。您好@Marc Gravell,请看一下。我在通过调试器获取调用列表方面也有类似的问题,不知道为什么它是空的?对于使用大量Windows控件尝试此操作并且无法找出原因的人,请选择复选框。选中更改的复选框和复选框。选中状态更改的复选框不起作用,请参见,您好,我不知道如何识别“事件\u FORMCLOSING”。如果我想列出某个特定表单的所有订阅活动,我应该如何做?
using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms;
class MyForm : Form
{
    public MyForm()
    { // assume we don't know this...
        Name = "My Form";
        FormClosing += Foo;
        FormClosing += Bar;
    }

    void Foo(object sender, FormClosingEventArgs e) { }
    void Bar(object sender, FormClosingEventArgs e) { }

    static void Main()
    {
        Form form = new MyForm();
        EventHandlerList events = (EventHandlerList)typeof(Component)
            .GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance)
            .GetValue(form, null);
        object key = typeof(Form)
            .GetField("EVENT_FORMCLOSING", BindingFlags.NonPublic | BindingFlags.Static)
            .GetValue(null);

        Delegate handlers = events[key];
        foreach (Delegate handler in handlers.GetInvocationList())
        {
            MethodInfo method = handler.Method;
            string name = handler.Target == null ? "" : handler.Target.ToString();
            if (handler.Target is Control) name = ((Control)handler.Target).Name;
            Console.WriteLine(name + "; " + method.DeclaringType.Name + "." + method.Name);
        }
    }
}