C# 使用反射将事件处理程序绑定到任何类型的事件
我有一些代码需要将事件动态绑定到事件处理程序:C# 使用反射将事件处理程序绑定到任何类型的事件,c#,.net,events,C#,.net,Events,我有一些代码需要将事件动态绑定到事件处理程序: foreach (string evnt in attribute.Events) { EventInfo ei = control.GetType().GetEvent(evnt); if(ei != null) { ei.AddEventHandler(control, new EventHandler((s, e) => { // More awesomen
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...
}));
}
}
var event_handler = new EventHandler((s, args) =>
{
// More awesomeness here...
});
因此,对于事件列表中的每个字符串,从控件中获取事件并绑定一个处理程序
问题在于并非所有事件都是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);
}
}
下面是如何使用helper类为将调用事件处理程序的不同事件处理程序类型创建不同委托的方法:
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);
}
现在,我们使用Delegate.CreateDelegate
为我们创建的特定HandlerHelper
对象基于handler
方法创建一个委托,并将该委托交给AddEventHandler
方法
出于性能原因,您可以基于事件参数类型缓存委托(而不是每次创建一个委托)。您可以使用动态关键字附加处理程序。您可以在此处找到更多解释:您当前拥有的有什么问题?@YacoubMassad-exception…类型为“System.EventHandler”的对象无法转换为类型为“System.Windows.Forms.KeyEventHandler”。@YacoubMassad基本上我需要表达式(s,e)=>{…}来应用于任何EventHander派生类型。在这种情况下,您不能;如果事件名称是字符串
(请参阅问题中的evnt
),则不适用。dynamic
关键字在这里没有任何帮助。你链接到的文章与“动态关键字”毫无关系。谢谢,@marcGraveli有一个错误:Type helper=typeof(handlehalper)。MakeGenericType(typeof(MouseEventArgs));提供的泛型参数的数量不等于泛型类型定义的arity。非常奇怪。我在发布之前测试了这段代码。您是否按原样复制了把手?它只有一个泛型参数,我们正在将一个类型传递给MakeGenericType
。这很奇怪。我将HandleHelper类复制到一个控制台应用程序中,并使用类型t=typeof(HandleHelper)进行测试;。。。。。工作得很好-然后在我的另一个解决方案中它就死了!。。。出于某种原因,它不喜欢HandleHelper是嵌套类!:-这可能就是我出错的地方
void Handle(object sender, MouseEventArgs args)