2009-03-31 13 views
8

可能なイベントごとにハンドラを明示的に作成しなくても、特定のWinFormsコントロールの起動イベントをすべて一覧表示する方法はありますか?たとえば、さまざまなデータバインドアクション中にDataGridViewとBindingSourceの間で発生する一連のイベントを確認することができます。イベントを発生させる制御を監視します。

答えて

8

を可能性が加入していないのであればイベントであっても解雇されていません反射を使用していますが、さまざまなイベントハンドラシグネチャが含まれているため、ややこしいことになります。基本的には、そのタイプのイベントごとにEventInfoを取得し、を呼び出す前にEventHandlerTypeプロパティを使用して、デリゲートタイプを作成します。 Delegate.CreateDelegateは、通常のイベントハンドラパターンに従うすべてのものに対して機能します。

サンプルアプリケーションです。それは何もチェックしていないことに注意してください - あなたが例外をスローする "非標準"イベントで何かを与えるなら、それは。あなたはかなり簡単に反射を使用してイベント引数を表示することもできます。

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

まさに私が探していたもの!私は真剣な読書や練習をリフレクションで行う必要があるように見えます。ありがとう! – BikeMrown

+0

非常に役に立ちました。ありがとうございました。 –

1

私はReflectionを使ってこれを行うことができると思います。

0

これはできません。あなたはフレームワークのクラスの多くを見るためにリフレクターを使用している場合は、イベントを発射したときには、一般的なパターンを見つけることができます:

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

を誰もあなたがそれに

+0

私はそれができないことを意味する理由がわかりません - それは単にイベントを購読する必要があることを意味します。コードとの間には、コード内の各イベントを明示的に*購読することと大きな違いがあります。 –

+0

私はあなたが髪を分割していると思います。ハードコードされたデリゲートを作成するか、またはリフレクションを使用することによって、まだイベントハンドラを「明示的に」追加しています。私の反応は、彼が(たとえリフレクションでも)イベントに全く加入したくないと仮定したが、他の方法でイベントのシーケンスを見たいと思った。 –

関連する問題