[英]Binding an event handler to any type of event using reflection
我有一些代码,我需要动态绑定事件到事件处理程序:
foreach (string evnt in attribute.Events)
{
EventInfo ei = control.GetType().GetEvent(evnt);
if(ei != null)
{
ei.AddEventHandler(control, new EventHandler((s, e) =>
{
// More awesomeness here...
}));
}
}
因此,对于事件列表中的每个字符串,从控件获取事件并绑定处理程序。
问题是并非所有事件都是EventHandler
,例如某些EventHandler
可能是KeyEventHander
或MouseEventHandler
等。
我不想要一个大量的if / else列表的EventHandler
派生类型,我只想绑定相同的处理程序,无论它是什么类型的EventHandler
。
我怎样才能做到这一点?
这是一种方法:
首先创建这个助手类:
public class HandlerHelper<T> where T : EventArgs
{
private readonly EventHandler m_HandlerToCall;
public HandlerHelper(EventHandler handler_to_call)
{
m_HandlerToCall = handler_to_call;
}
public void Handle(object sender, T args)
{
m_HandlerToCall.Invoke(sender, args);
}
}
这个泛型类有一个Handle
方法,它将用作许多事件处理程序类型的委托。 请注意,此类是通用的。 T
将是针对不同事件类型的许多EventArgs
派生类之一。
现在假设你定义了以下事件处理程序:
var event_handler = new EventHandler((s, args) =>
{
// More awesomeness here...
});
以下是如何使用helper类为将调用event_handler
的不同事件处理程序类型创建不同的委托:
foreach (var event_name in event_names)
{
var event_info = control.GetType().GetEvent(event_name);
var event_handler_type = event_info.EventHandlerType;
var event_args_type = event_handler_type.GetMethod("Invoke").GetParameters()[1].ParameterType;
var helper_type = typeof(HandlerHelper<>).MakeGenericType(event_args_type);
var helper = Activator.CreateInstance(helper_type, event_handler);
Delegate my_delegate = Delegate.CreateDelegate(event_handler_type, helper, "Handle");
event_info.AddEventHandler(button, my_delegate);
}
对于每个事件,我们获取EventHandlerType
,它类似于EventHandler
或MouseEventHandler
。
然后我们使用反射来获取第二个参数的类型,如EventArgs
或MouseEventArgs
。
然后我们根据EventArgs
参数的类型创建一个HandlerHelper<>
实例。 例如HandlerHelper<EventArgs>
或HandlerHelper<MouseEventArgs>
。
我们给event_handler
到的构造HandlerHelper
,以便它可以调用它时,它的Handle
方法被调用。
这使得Handle
方法的签名成为我们想要的。 例如,在HandlerHelper<MouseEventArgs>
的情况下, Handle
方法的签名是:
void Handle(object sender, MouseEventArgs args)
现在,我们使用Delegate.CreateDelegate
基于我们创建的特定HandlerHelper
对象的Handle
方法创建委托,并将这样的委托给予AddEventHandler
方法。
出于性能原因,您可以基于event_args_type
缓存委托(而不是每次创建一个委托)。
您可以使用动态关键字来附加处理程序。 您可以在此处找到更多解释: https : //msdn.microsoft.com/en-us/library/ms228976(v = vs.110).aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.