AddEventHandler using reflection
Here's a sample showing how to attach an event using reflection:
class Program
{
static void Main(string[] args)
{
var p = new Program();
var eventInfo = p.GetType().GetEvent("TestEvent");
var methodInfo = p.GetType().GetMethod("TestMethod");
Delegate handler =
Delegate.CreateDelegate(eventInfo.EventHandlerType,
p,
methodInfo);
eventInfo.AddEventHandler(p, handler);
p.Test();
}
public event Func<string> TestEvent;
public string TestMethod()
{
return "Hello World";
}
public void Test()
{
if (TestEvent != null)
{
Console.WriteLine(TestEvent());
}
}
}
Add Event Handler using Reflection ? / Get object of type?
Basically, what you have is fine. The only glitch is that myhandler
actually needs to be of the correct type, which is to say: of the type defined by the event.
For example:
using System;
using System.Collections.Specialized;
using System.Reflection;
class Program
{
static void Main()
{
Type AType = typeof(Foo);
var ObjectOfAType = new Foo();
Delegate myhandler = (NotifyCollectionChangedEventHandler)SomeHandler;
EventInfo info = AType.GetEvent("CollectionChanged");
info.AddEventHandler(ObjectOfAType, myhandler);
// prove it works
ObjectOfAType.OnCollectionChanged();
}
private static void SomeHandler(object sender, NotifyCollectionChangedEventArgs e)
=> Console.WriteLine("Handler invoked");
}
public class Foo
{
public void OnCollectionChanged() => CollectionChanged?.Invoke(this, null);
public event NotifyCollectionChangedEventHandler CollectionChanged;
}
There is a Delegate.CreateDelegate()
method that takes a delegate type, an object instance, and a MethodInfo
method; you can use this (using the event-type from EventInfo info
) to create an appropriate delegate instance for a given method on a particular object.
How to attach event handler to an event using reflection?
I think your code is failing because the HandleRfqSendComment
is private. Instead you could directly create a delegate to that method, without passing its name to CreateDelegate
. You would then need to convert the delegate to the required type, using the following method :
public static Delegate ConvertDelegate(Delegate originalDelegate, Type targetDelegateType)
{
return Delegate.CreateDelegate(
targetDelegateType,
originalDelegate.Target,
originalDelegate.Method);
}
In your code, you could use this method as follows :
EventInfo eventInfo = rfqWindowManager.GetType().GetEvent("SendComment");
Action<object, object> handler = HandleRfqSendComment;
Delegate convertedHandler = ConvertDelegate(handler, eventInfo.EventHandlerType);
eventInfo.AddEventHandler(rfqWindowManager, convertedHandler);
Add and remove async event handlers using reflection in c#
This should work:
var obj = new InstrumentInstance("foo");
EventCompletedHandler handler = async (s, e) => await ProcessInstrumentEvent(s, e);
foreach (var evt in obj.GetType().GetEvents(BindingFlags.Public | BindingFlags.Instance))
{
if (evt.EventHandlerType == typeof(EventCompletedHandler))
{
Console.WriteLine($"Binding '{evt.Name}'");
evt.AddEventHandler(obj, handler);
}
}
It should also work without the extra indirection:
EventCompletedHandler handler = ProcessInstrumentEvent;
Add and remove event handler via reflection c#
I think it's because you are creating a new handler each time: (which doesn't match the previous handler, so can't be removed from the invocation list)
public static void RemoveEventHandler(EventInfo eventInfo,
object item, Action action)
{
var parameters = GetParameters(eventInfo);
var handler = GetHandler(eventInfo, action, parameters); // <--
eventInfo.RemoveEventHandler(item, handler);
}
Why are you wrapping the Action
? To lose the parameters? It is not possible to add/remove the eventInfo.RemoveEventHandler(item, action);
because of the parameters. If you want to remove a newly generated handler, you should return that handler when you want to remove it.
public static Delegate AddEventHandler(EventInfo eventInfo, object item, Action action)
{
var parameters = GetParameters(eventInfo);
var handler = GetHandler(eventInfo, action, parameters);
eventInfo.AddEventHandler(item, handler);
return handler;
}
public static void RemoveEventHandler(EventInfo eventInfo,
object item, Delegate handler)
{
eventInfo.RemoveEventHandler(item, handler);
}
var handler = EventSubscriber.AddEventHandler(eventInfo, timer, TimerElapsed);
EventSubscriber.RemoveEventHandler(eventInfo, timer, handler);
How to add an event handler using reflection when do not have access to EventArgs type?
Actually, I figured it out.
I changed
var method = new DynamicMethod("MyHandlerImpl", null, new[] { typeof(object), myArgsType });
to
var method = new DynamicMethod("MyHandlerImpl", null, new[] { typeof(object), typeof(EventArgs) });
and made the Program
class public and everything worked.
Related Topics
What Are Some Reasons Networkstream.Read Would Hang/Block
Register a Dll into the Gac - But Then It Doesn't Show Up in the Assembly Window
Binding Listbox to List<Object> in Winforms
Inheritance with Base Class Constructor with Parameters
.Net 4.0 and the Dreaded Onuserpreferencechanged Hang
How to Include Quotes in a String
Get SQL Query from Linq to SQL
Capturing Binary Output from Process.Standardoutput
Why Can't I Assign a List<Derived> to a List<Base>
How to Find the State of Numlock, Capslock and Scrolllock in .Net
How Accurate Is Thread.Sleep(Timespan)
Win32_Processor::Is Processorid Unique for All Computers
String Concatenation VS String Builder. Performance
Lock (Monitor) Internal Implementation in .Net