确定绑定到事件的事件处理程序的列表
我有一个WinForms表单不会closures。 在OnFormClosing中,e.Cancel设置为true。 我猜测我的应用程序中的一些对象绑定到Closing或FormClosing事件,并阻止closures。 为了find答案,我想确定哪些代表与这些事件中的一个绑定。
有没有办法确定绑定到事件的处理程序列表? 理想情况下,我会通过Visual Studiodebugging器来执行此操作,但可以在应用程序中编写代码以在必要时查找处理程序。 了解事件就像一个隐藏的私人领域,我已经通过debugging器导航到我的窗体的“Windows.Forms.Form”祖先的“非公有领域”,但无济于事。
总之,你不打算这样做 – 但出于debugging目的…
一个事件往往由私人领域支持 – 但不是与控制; 他们使用EventHandlerList
方法。 您将不得不访问表单的protected Events
成员,查找映射到(私有)EVENT_FORMCLOSING对象的对象。
一旦你有FormClosingEventHandler
, GetInvocationList
应该做的工作。
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); } } }
问题可能是表单不validation。
FormClosing
事件由Form
的私有WmClose
方法引发,它将e.Cancel
初始化为!Validate(true)
。 我没有调查过,但在某些情况下, Validate
将始终返回false
,导致closures被取消,无论任何事件处理程序。
要调查这一点,请启用.Net源代码debugging ,在您的FormClosing
处理程序中放置一个断点,转到Form.WmClose
源Form.WmClose
(向上调用堆栈),在WmClose
开始处放置一个断点,然后再次closures窗体。 然后,在debugging器中查看它,看看为什么Validate
返回false
。 (或者哪个事件处理程序将e.Cancel
设置为true)
要解决这个问题,请在您自己的处理程序中将e.Cancel
设置为false
。