How to access the management event?

I am trying to get the name of the events assigned to control. For example, I have two forms: A and B. Form B contains a GridControl , and gridcontrol has events such as gridControl1_Validating .

My goal is to know what events are assigned to the control

My code is as follows FOrm A

public Control[] FilterControls(Control start, Func<Control, bool> isMatch) { var matches = new List<Control>(); Action<Control> filter = null; (filter = new Action<Control>(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); } 

ON compilation I get my control, but I get null in eventinfo Although the gridcontrol event has this event in form B

Please, help

+1
source share
1 answer

Try "Validating" instead of "gridControl1.Validating" "

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

Although this has nothing to do with the fact that you bound the event handler to the event. You yourself get the event, not the attached handlers. You cannot use anything with the eventInfo variable (another that adds and removes other event handlers).

To access the attached handlers (base delegates), you need to look at the code for implementing the events (using a decompiler, for example Reflector or dotPeek or using the Microsoft help source ):

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

It turns out that the Control class uses a property called Events type EventHandlerList to store all delegates based on the key field ( EventValidating in this case).

To get delegates for an event, we need to read them from the Events property:

 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; } 

and

 public static List<Delegate> RetrieveAllAttachedEventHandlers(Control c) { List<Delegate> result = new List<Delegate>(); 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; } 

The latter method will retrieve all event handlers associated with management events. This includes handlers from all classes (even internally bound winforms). You can also filter the list by the handler target:

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

Now you can get all gridControl1 event gridControl1 defined in formB :

 RetrieveAllAttachedEventHandlersInObject(gridControl1, formB); 
0
source

All Articles