2010-06-25 392 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); 
相關問題