2010-06-25 109 views
7

我知道EventInfo.AddEventHandler(...)方法可以用来附加处理程序的事件。但是,如果我甚至无法定义事件处理程序的正确签名,应如何处理,因为我甚至没有引用处理程序期望的事件参数。如何使用反射将事件处理程序附加到事件?

我将用正确的代码解释问题。

//我的解决方案中有一切可用的场景,即零反射场景。

internal class SendCommentsManager 
{ 
    public void Customize(IRFQWindowManager rfqWindowManager) 
    { 
     rfqWindowManager.SendComment += HandleRfqSendComment; 
    } 

    private void HandleRfqSendComment(object sender, SendCommentEventArgs args) 
    { 
     args.Cancel = true; 
    } 
} 

现在,我想通过反射来达到同样的目的。我已经能够找出它的大部分,但是当我附加一个委托给事件(使用AddEventHandler)时,它会抛出"Error binding to target method."异常。

我明白这个异常背后的原因,将错误的代表附加到事件。但必须有一些方法来实现这一点。

internal class SendCommentsManagerUsingReflection 
{ 
    public void Customize(IRFQWindowManager rfqWindowManager) 
    { 
     EventInfo eventInfo = rfqWindowManager.GetType().GetEvent("SendComment"); 
     eventInfo.AddEventHandler(rfqWindowManager, 
      Delegate.CreateDelegate(eventInfo.EventHandlerType, this, "HandleRfqSendComment")); 
     //<<<<<<<<<<ABOVE LINE IS WHERE I AM GOING WRONG>>>>>>>>>>>>>> 
    } 

    private void HandleRfqSendComment(object sender, object args) 
    { 
     Type sendCommentArgsType = args.GetType(); 
     PropertyInfo cancelProperty = sendCommentArgsType.GetProperty("Cancel"); 
     cancelProperty.SetValue(args, true, null); 
    } 
} 
+0

为什么不使用SendCommentEventArgs作为第二个参数? 顺便说一句:看看:http://msdn.microsoft.com/library/system.reflection.eventinfo.addeventhandler.aspx – Andreas 2010-06-25 22:19:34

+0

我不想引用具有“SendCommentEventArgs”的最新版本的dll。如果我可以使用“SendCommentEventArgs”,那么不需要使用反射来附加事件处理程序。 – 2010-06-26 09:11:23

回答

9

我觉得你的代码失败,因为HandleRfqSendComment是私人的。相反,您可以直接创建该方法的委托,而不必将其名称传递给CreateDelegate。然后,您将需要委托转换为所需的类型,使用下面的方法:

public static Delegate ConvertDelegate(Delegate originalDelegate, Type targetDelegateType) 
{ 
    return Delegate.CreateDelegate(
     targetDelegateType, 
     originalDelegate.Target, 
     originalDelegate.Method); 
} 

在你的代码,你可以按如下方式使用此方法:

EventInfo eventInfo = rfqWindowManager.GetType().GetEvent("SendComment"); 
Action<object, object> handler = HandleRfqSendComment; 
Delegate convertedHandler = ConvertDelegate(handler, eventInfo.EventHandlerType); 
eventInfo.AddEventHandler(rfqWindowManager, convertedHandler); 
相关问题