动态地将委托绑定到事件

本文关键字:绑定 事件 动态 | 更新日期: 2023-09-27 18:33:30

我有一个方法,它将页面上的方法绑定到动态创建的LinkButton

protected virtual void AddDynamicHandlerToControl(Page page, Control controlInstance,
            string methodName, string eventName)
{
   Delegate d = null;
   EventInfo ei = controlInstance.GetType().GetEvent(eventName);
   Type tDelegate = ei.EventHandlerType;
   MethodInfo method = page.GetType().BaseType.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
   if (method != null)
      d = Delegate.CreateDelegate(tDelegate, page, method);
   else {
      FieldInfo field = page.GetType().BaseType.GetField(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
      if (field != null)
      {
         d = field.GetValue(page) as Delegate;
      }
   }
   MethodInfo addHandler = ei.GetAddMethod();
   object[] addHandlerArgs = { d };
   addHandler.Invoke(controlInstance, addHandlerArgs);
}

这适用于该页面内的方法。我想添加的是支持用户控件中的方法。因此,我在页面代码隐藏中创建了一个delegate,并在运行时为其分配了用户控制方法。

我像这样创建和分配委托:

protected event PrintPageMethod PrintPage;
protected delegate void PrintPageMethod(object sender, EventArgs e);

然后:

PrintPage = DetailedTestsResult1.UserActionsForTests1_PrintPage;

代码尝试查找方法,如果未找到方法,则尝试查找委托的字段并找到正确的委托,该委托指向以用户控件类为目标的正确方法。

问题是,当达到addHandler.Invoke(controlInstance, addHandlerArgs);时,它会作为异常抛出

类型为"SomePage+PrintPageMethod"的对象不能转换为类型"System.EventHandler"。

无法弄清楚我做错了什么。

动态地将委托绑定到事件

而不是:

protected event PrintPageMethod PrintPage;
protected delegate void PrintPageMethod(object sender, EventArgs e);

用:

protected event EventHandler PrintPage;

尽管签名相似,但委托类型不同。

不能将委托转换为其他委托。

d = field.GetValue(page) as Delegate;

Delegate orig = field.GetValue(page) as Delegate;
d = Delegate.Combine(
    orig.GetInvocationList()
    .Select(_ => Delegate.CreateDelegate(tDelegate, _.Target, _.Method))
    .ToArray()
    );

您可以使用来自 .Target.Method 的调用目标创建另一个Delegate,如果委托有多个目标,则必须合并每个委托。