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