如何访问控件的事件?

我试图得到分配给控制的事件的名称例如:我有两个formsAB. 表单B包含GridControl ,gridcontrol有一些事件,如gridControl1_Validating。

我的目标只是知道分配给控件的事件是什么

我的守则如下FOrm A.

public Control[] FilterControls(Control start, Func isMatch) { var matches = new List(); Action filter = null; (filter = new Action(c => { if (isMatch(c)) matches.Add(c); foreach (Control c2 in c.Controls) filter(c2); }))(start); return matches.ToArray(); } static void main[] { Control[] FoundControls = null; FoundControls = FilterControls(TF, c => c.Name != null && c.Name.StartsWith("grid")); var eventinfo = FoundControls[0].GetType().GetEvent("gridControl1.Validating", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); } 

在编译时,我得到了我的控件,但我在eventinfo处于null,尽管gridcontrol事件在表单B中有此事件

请帮忙

尝试"Validating"而不是"gridControl1.Validating"

 var eventinfo = FoundControls[0].GetType().GetEvent( "Validating", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 

虽然这与您已将事件处理程序附加到事件的事实无关。 您正在获取事件本身,而不是附加的处理程序。 您无法对eventInfo变量执行任何有用的eventInfo (除了添加和删除其他事件处理程序之外)。

要访问附加的处理程序(底层委托),您需要查看事件实现的代码(使用reflection器或dotPeek等反编译器 ,或使用Microsoft Reference Source ):

 public event CancelEventHandler Validating { add { base.Events.AddHandler(EventValidating, value); } remove { base.Events.RemoveHandler(EventValidating, value); } } 

事实certificate, Control类使用名为EventsEventHandlerList类型的属性来存储基于键的所有委托(在本例中为EventValidating字段)。

要检索事件的委托,我们应该从Events属性中读取它们:

 public static Delegate[] RetrieveControlEventHandlers(Control c, string eventName) { Type type = c.GetType(); FieldInfo eventKeyField = GetStaticNonPublicFieldInfo(type, "Event" + eventName); if (eventKeyField == null) { eventKeyField = GetStaticNonPublicFieldInfo(type, "EVENT_" + eventName.ToUpper()); if (eventKeyField == null) { // Not all events in the WinForms controls use this pattern. // Other methods can be used to search for the event handlers if required. return null; } } object eventKey = eventKeyField.GetValue(c); PropertyInfo pi = type.GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance); EventHandlerList list = (EventHandlerList)pi.GetValue(c, null); Delegate del = list[eventKey]; if (del == null) return null; return del.GetInvocationList(); } // Also searches up the inheritance hierarchy private static FieldInfo GetStaticNonPublicFieldInfo(Type type, string name) { FieldInfo fi; do { fi = type.GetField(name, BindingFlags.Static | BindingFlags.NonPublic); type = type.BaseType; } while (fi == null && type != null); return fi; } 

 public static List RetrieveAllAttachedEventHandlers(Control c) { List result = new List(); foreach (EventInfo ei in c.GetType().GetEvents()) { var handlers = RetrieveControlEventHandlers(c, ei.Name); if (handlers != null) // Does it have any attached handler? result.AddRange(handlers); } return result; } 

最后一个方法将提取附加到控件事件的所有事件处理程序。 这包括来自所有类的处理程序(甚至由winforms内部附加)。 您还可以通过处理程序的目标对象筛选列表:

 public static List RetrieveAllAttachedEventHandlersInObject(Control c, object handlerContainerObject) { return RetrieveAllAttachedEventHandlers(c).Where(d => d.Target == handlerContainerObject).ToList(); } 

现在,您可以获取formB定义的formB所有事件处理程序:

 RetrieveAllAttachedEventHandlersInObject(gridControl1, formB);