2010-06-25 18 views
7

Wiem o metodzie EventInfo.AddEventHandler(...), której można użyć do dołączenia programu obsługi do zdarzenia. Ale co należy zrobić, jeśli nie mogę nawet zdefiniować właściwego podpisu procedury obsługi zdarzeń, tak jak w, nie mam nawet odniesienia do argumentów zdarzeń oczekiwanych przez program obsługi?Jak dołączyć obsługę zdarzeń do zdarzenia za pomocą odbicia?

Opiszę problem za pomocą odpowiedniego kodu.

// Scenariusz, gdy mam wszystko dostępne w moim rozwiązaniu, scenariusz Zero Reflection.

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

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

Teraz chcę osiągnąć ten sam cel za pomocą refleksji. Udało mi się rozgryźć większość z nich, ale kiedy dołączam delegata do zdarzenia (przy użyciu AddEventHandler), generuje on wyjątek "Error binding to target method.".

Rozumiem przyczynę tego wyjątku, dołączając niewłaściwego delegata do wydarzenia. Ale musi być jakiś sposób, aby to osiągnąć.

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

Dlaczego nie skorzystać SendCommentEventArgs jako drugi argument ? BTW: Zajrzyj na: http://msdn.microsoft.com/library/system.reflection.eventinfo.addeventhandler.aspx – Andreas

+0

Nie chcę odwoływać się do najnowszej wersji biblioteki dll z "SendCommentEventArgs". Jeśli mógłbym użyć "SendCommentEventArgs", nie ma potrzeby dołączania obsługi zdarzeń za pomocą odbicia. –

Odpowiedz

9

Myślę, że Twój kod się niepowodzeniem, ponieważ HandleRfqSendComment jest prywatny. Zamiast tego możesz bezpośrednio utworzyć delegata do tej metody, nie przekazując jej nazwy CreateDelegate. Będziesz wtedy trzeba konwertować delegata do wymaganego typu, stosując następujące metody:

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

w kodzie, można użyć tej metody w następujący sposób:

EventInfo eventInfo = rfqWindowManager.GetType().GetEvent("SendComment"); 
Action<object, object> handler = HandleRfqSendComment; 
Delegate convertedHandler = ConvertDelegate(handler, eventInfo.EventHandlerType); 
eventInfo.AddEventHandler(rfqWindowManager, convertedHandler); 
Powiązane problemy