Aviad's post is a good start. You can use it for events of type EventHandler
. For other delegate types you can use the same technique creating handler for each type manually.
If you want to be more flexible you should create event handler in runtime using System.Reflection.Emit
. Here is a detailed explanation: http://msdn.microsoft.com/en-us/library/ms228976.aspx. Scroll down to "To generate an event handler at run time by using a dynamic method" title.
//EDIT
I created simple class which is able to handle all events of particular object and pass them to universal event handler. Code is based on examples from Microsoft and XTreme.NET Talk.
Basic idea
- create method in runtime which has the same arguments as event
- set this mehod as event handler for each event in Type.GetEvents()
- from this method call universal event handler
Usage
Object to attach to is passed in constructor. Next anonymous method of type UniversalEventHandler
is used to handle all events. This method receives event name as eventName
and event arguments in args
. You can set breakpoint on this method and inspect arguments in Visual Studio or print them by yourself. In this sample usage only event name is printed and can be found in Output window (menu View > Output in Visual Studio). In this example standard button button1
is examined.
private void Form1_Load(object sender, EventArgs e)
{
UniversalEventHandler handler = (UniversalEventHandler) delegate(string eventName, object[] args)
{
System.Diagnostics.Trace.WriteLine(eventName);
};
EventInspector inspector = new EventInspector(button1, handler);
}
Code
public delegate void UniversalEventHandler(string eventName, object[] args);
public class EventInspector
{
private UniversalEventHandler eventHandler;
private object srcObject;
public EventInspector(object srcObject, UniversalEventHandler eventHandler)
{
this.eventHandler = eventHandler;
this.srcObject = srcObject;
Attach();
}
public void EventReceived(string eventName, object[] args)
{
if (eventHandler != null)
eventHandler(eventName, args);
}
public void Attach()
{
Type type = srcObject.GetType();
EventInfo[] srcEvents = type.GetEvents();
for (int i = 0; i < srcEvents.Length; i++)
{
EventInfo srcEvent = srcEvents[i];
Type[] parameterTypes = GetDelegateParams(srcEvent.EventHandlerType);
DynamicMethod handler = new DynamicMethod("", typeof(void), parameterTypes, typeof(EventInspector));
string name = srcEvent.Name;
ILGenerator il = handler.GetILGenerator();
il.DeclareLocal(typeof(object[]));
il.DeclareLocal(typeof(string));
il.Emit(OpCodes.Ldstr, srcEvent.Name);
il.Emit(OpCodes.Stloc_1);
il.Emit(OpCodes.Ldc_I4, parameterTypes.Length - 1);
il.Emit(OpCodes.Newarr, typeof(object));
il.Emit(OpCodes.Stloc_0);
for (int j = 0; j < parameterTypes.Length - 1; j++)
{
Type parameter = parameterTypes[j];
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldc_I4, j);
il.Emit(OpCodes.Ldarg, j + 1);
il.Emit(OpCodes.Stelem_Ref);
}
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldloc_1);
il.Emit(OpCodes.Ldloc_0);
MethodInfo eventReceivedMethod = this.GetType().GetMethod("EventReceived", BindingFlags.Public | BindingFlags.Instance);
il.EmitCall(OpCodes.Callvirt, eventReceivedMethod, null);
il.Emit(System.Reflection.Emit.OpCodes.Ret);
srcEvent.AddEventHandler(srcObject, handler.CreateDelegate(srcEvent.EventHandlerType, this));
}
}
private Type[] GetDelegateParams(Type d)
{
MethodInfo delegateMethod = d.GetMethod("Invoke");
ParameterInfo[] delegateParams = delegateMethod.GetParameters();
Type[] result = new Type[delegateParams.Length + 1];
result[0] = this.GetType();
for (int i = 0; i < delegateParams.Length; i++)
{
result[i + 1] = delegateParams[i].ParameterType;
}
return result;
}
}