2009-03-31 11 views

risposta

8

Si potrebbe utilizzare la riflessione, ma sarà leggermente complicato a causa delle varie firme del gestore eventi coinvolte. Fondamentalmente si dovrebbe ottenere il EventInfo per ogni evento nel tipo e utilizzare la proprietà EventHandlerType per determinare quale tipo di delegato creare prima di chiamare AddEventHandler. Delegate.CreateDelegate funziona per tutto ciò che segue il normale modello di gestore eventi ...

Ecco un'app campione. Nota che non sta facendo alcun controllo - se gli dai qualcosa con un evento "non standard" genererà un'eccezione. Si potrebbe tranquillamente usare la riflessione per stampare anche gli argomenti dell'evento.

using System; 
using System.Drawing; 
using System.Windows.Forms; 
using System.Reflection; 

namespace ConsoleApp 
{ 
    class Program 
    { 
     [STAThread] 
     static void Main(string[] args) 
     { 
      Form form = new Form { Size = new Size(400, 200) }; 
      Button button = new Button { Text = "Click me" }; 
      form.Controls.Add(button); 
      EventSubscriber.SubscribeAll(button); 
      Application.Run(form); 
     } 
    } 

    class EventSubscriber 
    { 
     private static readonly MethodInfo HandleMethod = 
      typeof(EventSubscriber) 
       .GetMethod("HandleEvent", 
          BindingFlags.Instance | 
          BindingFlags.NonPublic); 

     private readonly EventInfo evt; 

     private EventSubscriber(EventInfo evt) 
     { 
      this.evt = evt; 
     } 

     private void HandleEvent(object sender, EventArgs args) 
     { 
      Console.WriteLine("Event {0} fired", evt.Name); 
     } 

     private void Subscribe(object target) 
     { 
      Delegate handler = Delegate.CreateDelegate(
       evt.EventHandlerType, this, HandleMethod); 
      evt.AddEventHandler(target, handler); 
     } 

     public static void SubscribeAll(object target) 
     { 
      foreach (EventInfo evt in target.GetType().GetEvents()) 
      { 
       EventSubscriber subscriber = new EventSubscriber(evt); 
       subscriber.Subscribe(target); 
      } 
     } 
    } 
} 
+1

Esattamente quello che stavo cercando! Sembra che ho bisogno di leggere seriamente e armeggiare di riflessioni. Grazie! – BikeMrown

+0

Molto utile, davvero. Grazie. –

1

Penso che potresti usare Reflection per farlo.

0

Questo non può essere fatto. Se si utilizza Reflector per vedere un sacco di classi del Framework troverete un modello comune quando spara eventi:

// fire event 
if (EventDelegate != null) 
    EventDelegate(eventArgs); 

Quindi l'evento non è nemmeno licenziati se nessuno sta sottoscrivendo ad esso

+0

Non vedo perché questo significa che non può essere fatto, significa solo che l'evento deve essere sottoscritto. C'è una grande differenza tra questo e * esplicitamente * l'iscrizione a ogni evento nel codice. –

+0

Penso che stai dividendo i capelli. O creando dei delegati con codice fisso o usando la reflection, stai ancora "esplicitamente" aggiungendo i gestori di eventi. La mia risposta presupponeva che non volesse sottoscrivere gli eventi (anche attraverso la riflessione), ma voleva vedere la sequenza degli eventi in qualche altro modo. –

Problemi correlati