[英]Pass extra parameter to event with reflection
我正在使用反射将事件从Web控件绑定到我自己的方法。 这是一个通用函数,因此我事先不知道控件或事件的类型,但是事件是例如单击(按钮)或selectedIndexChanged(下拉列表)。 我的函数如下所示:
protected void BindEvents(WebControl ctrl, string methodName, string eventType)
{
System.Reflection.EventInfo eventInfo = ctrl.GetType().GetEvent(eventType);
Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, methodName);
eventInfo.AddEventHandler(ctrl, handler);
}
我需要通过传入一个额外的参数来了解哪个事件触发了MyEvent(请参见下文)。 这很重要,因为每个Web控件都可以有许多调用MyEvent的事件。
//1. Standard event signature
protected void Test_Click(object sender, EventArgs e) { }
//2. Signature for my event
protected void MyEvent(object sender, EventArgs e, string eventName) { }
创建委托时,不允许具有不同的签名,该代码仅在删除最后一个参数string eventName
。 我尝试通过将eventName设置为默认参数来尝试解决方法。 我也尝试过子类化EventArgs,但不允许对标准签名进行任何更改。 我可以重写控制事件以适应我的签名,但我认为必须有一种更简单的方法。
使用反射时,有什么方法可以将这个额外的参数传递给函数?
尽管不是很漂亮,但这可以解决问题:
protected void BindEvents(WebControl ctrl, string methodName, string eventType)
{
System.Reflection.EventInfo eventInfo = ctrl.GetType().GetEvent(eventType);
var delegateType = eventInfo.EventHandlerType.GetMethod("Invoke");
var methodInfo = this.GetType().GetMethod(methodName);
var parameters = delegateType.GetParameters();
if (parameters.Length!=2)
throw new NotImplementedException(); // Can make switch and multiple CreateAction methods to handle
var genericCreateAction = this.GetType().GetMethod("CreateAction2");
var parameterTypes = parameters.Select(o => o.ParameterType).ToArray<Type>();
var createAction = genericCreateAction.MakeGenericMethod(parameterTypes);
var action = (Delegate)createAction.Invoke(this, new object[] { methodInfo, eventType });
var properTypeAction = Delegate.CreateDelegate(eventInfo.EventHandlerType, action.Target, action.Method);
eventInfo.AddEventHandler(ctrl, properTypeAction);
}
public Action<T1, T2> CreateAction2<T1, T2>(MethodInfo methodInfo, string eventName)
{
return (Action<T1, T2>)((p1, p2) => { methodInfo.Invoke(this, new object[] { p1, p2, eventName }); });
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.