C#使用反射从表单控件访问事件名称

C#使用反射从表单控件访问事件名称,c#,winforms,events,reflection,C#,Winforms,Events,Reflection,我目前正在开发一个正在进行的解决方案,它采用一个包含表单的程序集,创建这些表单的实例,然后从中提取控件。到目前为止一切都很好。然而,我得到了另一个请求,我发现很难实现 我现在需要做的是在运行时提取与表单上每个控件关联的事件(特别是实际的事件名称和事件类型)。为了实现这一点,我创建了一个非常简单的winforms项目来模拟我将在完成的应用程序中所做的工作 我已经尝试了各种方法来获取这些事件,目前为止,我最接近的方法是: EventHandlerList events = this.button1.

我目前正在开发一个正在进行的解决方案,它采用一个包含表单的程序集,创建这些表单的实例,然后从中提取控件。到目前为止一切都很好。然而,我得到了另一个请求,我发现很难实现

我现在需要做的是在运行时提取与表单上每个控件关联的事件(特别是实际的事件名称和事件类型)。为了实现这一点,我创建了一个非常简单的winforms项目来模拟我将在完成的应用程序中所做的工作

我已经尝试了各种方法来获取这些事件,目前为止,我最接近的方法是:

EventHandlerList events = this.button1.GetType()
                                      .GetProperty("Events", BindingFlags.Instance | 
                                                             BindingFlags.Public |
                                                             BindingFlags.Static | 
                                                             BindingFlags.NonPublic)
                                      .GetValue(this.button1) as EventHandlerList;
在我的按钮中,我为点击和鼠标离开创建了两个事件。当我调试上面的代码并检查事件时,我可以看到我创建的两个事件,但它们存在于“None public members\head”下

我在调试模式下看到的事件如下所示:

{Method={Void button1\u MouseLeave(System.Object,System.EventArgs)}

根据关于另一个表单的建议,我尝试了以下方法,以查看是否可以创建事件的委托(但没有成功):


我不知道接下来该怎么办。我似乎就快到了,因为我可以在调试模式下看到事件,但我不确定如何获取它们的名称。

你说得对,你就快到了,只是EventHandlerList是一个不容易定义的链接列表。您可以在此处查看源代码:

这将为您提供控件(WinForms)的所有订阅事件

var myEvent = events["button1_MouseLeave"];
        EventHandlerList events = (EventHandlerList)typeof(Component)
               .GetField("events", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField)
               .GetValue(this);

        object current = events.GetType()
               .GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField)[0]
               .GetValue(events);

        List<Delegate> delegates = new List<Delegate>();
        while(current != null)
        {
            delegates.Add((Delegate)GetField(current,"handler"));
            current = GetField(current,"next");
        }
        public static object GetField(object listItem, string fieldName)
        {
            return listItem.GetType()
               .GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField)
               .GetValue(listItem);
        }