确定绑定到事件的事件处理程序的列表 [英] Determine list of event handlers bound to event
问题描述
有没有办法确定绑定到事件的处理程序的列表?理想情况下,我将通过Visual Studio调试器执行此操作,但可以在应用程序中编写代码,以便在必要时查找处理程序。了解一个事件就像一个隐藏的私有字段,我已经通过调试器导航到我的窗体的Windows.Forms.Form祖先的非公共字段,但无济于事。
简而言之,您不是要这样做 - 而是用于调试目的...
事件通常由私人字段支持,但不是控件;他们使用 EventHandlerList
方法。您必须访问表单的受保护的事件
成员,寻找映射到(私人)EVENT_FORMCLOSING对象的对象。
一旦你有 FormClosingEventHandler
, GetInvocationList
应该做这个工作。
using System;
使用System.ComponentModel;
使用System.Reflection;
使用System.Windows.Forms;
class MyForm:Form
{
public MyForm()
{//假设我们不知道这个...
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);
代理处理程序=事件[key];
foreach(Handlers.GetInvocationList()中的委托处理程序)
{
MethodInfo method = handler.Method;
string name = handler.Target == null? :handler.Target.ToString();
if(handler.Target是Control)name =((Control)handler.Target).Name;
Console.WriteLine(name +;+ method.DeclaringType.Name +。+ method.Name);
}
}
}
I have a WinForms form that won't close. In OnFormClosing, e.Cancel is set to true. I am guessing that some object in my application has bound to the Closing or FormClosing event, and is blocking the close. To find out, I'd like to determine what delegates are bound to one of these events.
Is there a way to determine the list of handlers bound to an event? Ideally I would do this via the Visual Studio debugger, but can write code in the application to find the handlers if necessary. Understanding that an event is like a hidden private field, I've navigated through the Debugger to the "Non-Public Fields" for the "Windows.Forms.Form" ancestor of my form, but to no avail.
In short, you're not meant to do this - but for debugging purposes...
An event is often backed by a private field - but not with controls; they use the EventHandlerList
approach. You would have to access the form's protected Events
member, looking for the object mapped to the (private) EVENT_FORMCLOSING object.
Once you have the FormClosingEventHandler
, GetInvocationList
should do the job.
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);
}
}
}
这篇关于确定绑定到事件的事件处理程序的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!