2009-03-31 36 views
8

Belirli bir WinForms denetimi için tüm olası olayları açık bir şekilde her olası olay için bir işleyici oluşturmadan listelemenin bir yolu var mı? Örneğin, çeşitli veri bağlama eylemleri sırasında DataGridView ve BindingSource arasında yanan olayların sırasını görmek isteyebilirim.İşlenmekte olan olayları belirlemek için denetimi izleyin.

cevap

8

Yapabilirsin Yansıma kullanın, ancak çeşitli olay eylemci imzaları nedeniyle biraz zor olacak. Temel olarak, türündeki her olay için EventInfo'u almanız ve numaralı telefonu aramadan önce hangi temsilci türünün oluşturulacağını öğrenmek için EventHandlerType özelliğini kullanın. Delegate.CreateDelegate, normal olay işleyici desenini izleyen her şey için çalışıyor ...

İşte örnek bir uygulama. Herhangi bir kontrol yapmamaya dikkat edin - bir "standart olmayan" olay ile bir şey verirseniz bir istisna atar. Olay arşivlerini de yazdırmak için yansımayı kolayca kullanabilirsiniz.

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

Tam olarak aradığım şey! Görünüşe göre ciddi bir okuma yapmalı ve yansıma ile uğraşmam gerek. Teşekkürler! – BikeMrown

+0

Gerçekten çok yardımcı. Teşekkür ederim. –

1

Bunu yapmak için Reflection'ı kullanabileceğinizi düşünüyorum.

0

Bu yapılamaz. Eğer Taslak'ta birçok sınıfı görüntülemek için Reflektör kullanırsanız olayları ateş ederken ortak bir desen bulabilirsiniz: kimsenin abone ise

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

Dolayısıyla etkinlik bile ateş edilmez

+0

Bunun neden yapılmadığını anlamıyorum - yalnızca olayın abone olması gerektiği anlamına gelir. Bunlar arasında büyük bir fark vardır ve * koddaki her etkinliğe * açıkça * abone olur. –

+0

Bence saçları bölüyorsun. Sabit kodlanmış delegeler oluşturarak veya yansıma kullanarak, hala olay işleyicileri ekleyerek 'açıkça' katılıyorsunuz demektir. Benim cevabım, olaylara (yansıma aracılığıyla bile) abone olmak istemediğini, ancak başka bir şekilde olayların sırasını görmek istediğini varsaydı. –

İlgili konular