2010-11-05 14 views
7

Ho una classe molto semplice:Iscriviti a un evento con la riflessione

class Trace 
{ 
    void WriteTrace() 
    { 
     Console.WriteLine("Trace !"); 
    } 
} 

voglio questa classe sottoscrive un evento, ad esempio l'evento carico di un controllo di modulo. Il controllo e l'evento sono definire dinamicamente quindi voglio usare riflessione per fare questo una cosa che sto cercando così:

Nella mia classe Trace ho questo metodo:

public void SubscribeEvent (Control control) 
{ 
     if (type.IsAssignableFrom(control.GetType())) 
     { 
      Trace test = this; 
      MethodInfo method = typeof(Trace).GetMethod("WriteTrace"); 

      // Subscribe to the event 
      EventInfo eventInfo = control.GetType().GetEvent("Load"); // We suppose control is a form 
      Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, control, method); // ERROR : Error binding to target method 

     } 
    } 
} 

C'è un errore sul ultima riga: errore di associazione al metodo di destinazione. Cosa c'è che non va nel mio snippet?

Grazie!

EDIT: Ok, non c'è più errore ma quando l'evento "Load" viene sollevato dal Form, il metodo WriteTrace non viene chiamato (ho inserito un punto di interruzione ma non è stato raggiunto). Perché ?

Ci scusiamo per la modifica, funziona molto bene :)

+0

Perché si desidera utilizzare Reflection se si potesse semplicemente iscriversi/aggiungere un gestore all'evento? 'control.Load + = HandlerHere;' ... D'altra parte, hai emanato rito 'Form' invece di' Control'? Perché stai parlando per la prima volta di un modulo. – Bobby

+0

Ecco un esempio ma dovrei essere in grado di scegliere il controllo e gli eventi da tracciare. – Florian

risposta

8

Con alcune modifiche, sono stato in grado di eseguire il campione.

In primo luogo, il metodo su Trace deve avere una firma diversa per corrispondere al tipo EventHandler:

public class Trace 
{ 
    public void WriteTrace(object sender, EventArgs e) 
    { 
     Console.WriteLine("Trace !"); 
    } 
} 

Successivamente, sono state fatte al SubscribeEvent alcune modifiche:

public void SubscribeEvent(Control control) 
{ 
    if (typeof(Control).IsAssignableFrom(control.GetType())) 
    { 
     Trace test = this; 
     MethodInfo method = typeof(Trace).GetMethod("WriteTrace"); 

     EventInfo eventInfo = control.GetType().GetEvent("Load"); 

     // Create the delegate on the test class because that's where the 
     // method is. This corresponds with `new EventHandler(test.WriteTrace)`. 
     Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, test, method); 
     // Assign the eventhandler. This corresponds with `control.Load += ...`. 
     eventInfo.AddEventHandler(control, handler); 
    } 
} 

Spero aiuta.

1

Il primo problema è che la firma metodo Trace.WriteTrace non corrisponde alla sintassi Form.Load gestore di eventi

Prova questo:

void WriteTrace(object sender, EventArgs e) 
{ 
    Console.WriteLine("Trace !"); 
} 

Inoltre, la chiamata a CreateDelegate deve passare l'oggetto di traccia, non l'oggetto di controllo:

Trace test = this; 
MethodInfo method = typeof(Trace).GetMethod("WriteTrace"); 

// Subscribe to the event 
EventInfo eventInfo = control.GetType().GetEvent("Load"); // We suppose control is a form 

Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, method); // ERROR : Error binding to target method 
eventInfo.AddEventHandler(control, handler); 
Problemi correlati