How can I programmatically subscribe to all events of an object?

I'm trying to subscribe to ALL events presented by a third-party WPF GridView component to do some debugging. Besides the suggestion that this may not be the best way to debug it and all that I would like to know if this can be done.

For routed events, it worked fine:

var type = tree.GetType(); do { var staticFields = type.GetFields(BindingFlags.Static | BindingFlags.Public); foreach (var staticField in staticFields) { if (typeof(RoutedEvent).IsAssignableFrom(staticField.FieldType)) { tree.AddHandler((RoutedEvent)staticField.GetValue(null), new RoutedEventHandler(OnRoutedEvent), true); } } } while ((type = type.BaseType) != typeof(object)/* && type.FullName.StartsWith("Telerik")*/); public void OnRoutedEvent(object sender, System.Windows.RoutedEventArgs e) { Debug.WriteLine(e.RoutedEvent.ToString()); } 

However, with typical events this does not work:

 var evts = tree.GetType().GetEvents(); foreach (var ev in evts) { ev.AddEventHandler(this, new EventHandler(OnEvent)); } public void OnEvent(object sender, EventArgs e) { //.. } 

because he doesnโ€™t like the fact that the delegate is an EventHandler instead of a specialized type or because the signature of the event handler method does not contain a specialized type of the EventArgs class.

How can I do that?

------------ LATER EDIT --------- In all three cases (my attempt, the ds27680 sentence and the Thomas Levesque sentence), the AddEventHandler call fails:

  System.Reflection.TargetException occurred Message=Object does not match target type. Source=mscorlib StackTrace: at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Reflection.EventInfo.AddEventHandler(Object target, Delegate handler) at Test.MainWindow..ctor() in c:\users\me\documents\visual studio 2010\Projects\Test\Test\MainWindow.xaml.cs:line 39 

I assume that the signature of the event handler method does not match EXACTLY, the EventArgs type is what causes it to crash ...

+4
source share
3 answers

You can try:

 public class DebugHook { public static void OnEvent<EventArgsType>(object sender, EventArgsType eventArgs) { } } 

then

 foreach (var ev in evts) { Type argsType = getEventArgsType(ev); MethodInfo hook = typeof(DebugHook).GetMethod("OnEvent"); MethodInfo boundEventhandler = hook.MakeGenericMethod(new [] { argsType} ); Delegate handler = Delegate.CreateDelegate(ev.EventHandlerType, boundEventhandler); ev.AddEventHandler(this, handler ); } 

where getEventArgs looks like this:

  public Type getEventArgsType(EventInfo eventType) { Type t = eventType.EventHandlerType; MethodInfo m = t.GetMethod("Invoke"); var parameters = m.GetParameters(); return parameters[1].ParameterType; } 

Of course, there is no error checking / error handling ...

+2
source

You need to "convert" the delegate to the appropriate type:

 var evts = tree.GetType().GetEvents(); EventHandler tmp = OnEvent; foreach (var ev in evts) { Delegate handler = Delegate.CreateDelegate(ev.EventHandlerType, tmp.Target, tmp.Method); ev.AddEventHandler(this, handler); } 
+2
source

You can create events of a specific type using Delegate.CreateDelegate . Worth a try.

+1
source

Source: https://habr.com/ru/post/1345518/


All Articles