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