2010-06-25 10 views
7

Conosco il metodo EventInfo.AddEventHandler(...) che può essere utilizzato per associare il gestore a un evento. Ma cosa si dovrebbe fare se non riesco nemmeno a definire la firma corretta del gestore di eventi, come in, non ho nemmeno riferimenti agli argomenti degli eventi previsti dal gestore?Come associare il gestore di eventi a un evento utilizzando la riflessione?

Spiegherò il problema con il codice corretto.

// Scenario quando ho tutto disponibile nella mia soluzione, Zero Reflection Scenario.

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

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

Ora, voglio raggiungere lo stesso obiettivo utilizzando la riflessione. Sono stato in grado di capire la maggior parte di esso ma quando collego un delegato all'evento (utilizzando AddEventHandler) genera l'eccezione "Error binding to target method.".

Ho compreso il motivo di questa eccezione, associando un delegato errato a un evento. Ma ci deve essere un modo per raggiungere questo obiettivo.

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

perché non utilizzare SendCommentEventArgs come secondo argomento ? BTW: Dai un'occhiata a: http://msdn.microsoft.com/library/system.reflection.eventinfo.addeventhandler.aspx – Andreas

+0

Non voglio fare riferimento all'ultima versione di dll con "SendCommentEventArgs". Se potessi usare "SendCommentEventArgs", non è necessario allegare il gestore di eventi usando la reflection. –

risposta

9

Credo che il codice sta fallendo perché il HandleRfqSendComment è privato. Invece è possibile creare direttamente un delegato per quel metodo, senza passare il suo nome a CreateDelegate. Si sarebbe quindi bisogno di convertire il delegato al tipo desiderato, utilizzando il seguente metodo:

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

Nel codice, è possibile utilizzare questo metodo come segue:

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