tutorial example event delegate custom c# winforms delegates event-handling controls

c# - example - ¿Cómo acceder al evento del control?



handler c# example (1)

Estoy tratando de obtener el nombre de los eventos que se asignan para controlar Por ejemplo: Tengo dos formularios A y B. La Forma B contiene GridControl y gridcontrol tiene algunos eventos como gridControl1_Validating .

mi objetivo es solo saber cuáles son los eventos asignados al control

Mi código es el siguiente 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); }

Al compilar obtengo mi control, pero estoy obteniendo nulo en eventinfo Aunque el evento gridcontrol tiene este evento en el formulario B

Por favor ayuda


Pruebe con "Validating" lugar de "gridControl1.Validating" "

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

Aunque esto no tiene nada que ver con el hecho de que haya adjuntado un controlador de eventos al evento. Obtendrá el evento en sí, no los controladores adjuntos. No puede hacer nada útil con la variable eventInfo (otra que agrega y elimina otros controladores de eventos).

Para acceder a los manejadores adjuntos (delegados subyacentes) necesita mirar el código para las implementaciones de eventos (usando un decompilador como Reflector o dotPeek , o usando el Origen de Referencia de Microsoft ):

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

Resulta que la clase Control usa una propiedad llamada Events de tipo EventHandlerList para almacenar todos los delegados basados ​​en una clave (campo EventValidating en este caso).

Para recuperar delegados para un evento, debemos leerlos desde la propiedad 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; }

y

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

El último método extraerá todos los manejadores de eventos adjuntos a los eventos de control. Esto incluye controladores de todas las clases (incluso vinculadas internamente por winforms). También puede filtrar la lista por el objeto de destino del controlador:

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

Ahora puede obtener todos los controladores de eventos de gridControl1 definidos en formB :

RetrieveAllAttachedEventHandlersInObject(gridControl1, formB);