2016-04-26 14 views
0

たとえば、winformでは、winformにbutton1という名前のボタンをドラッグします。デリゲートにバインドする関数名を取得する方法

this.button1.Click += new System.EventHandler(this.button1_Click); 
this.button1.Click += new System.EventHandler(this.Alert); 

答えはどうやってコード内のbutton1にバインドされた関数名を取得できますか?

私は関数名を取得したいと思って、button1についてのソースコードを見つけるために名前を使用したいと思います。ユーザーがbutton1をクリックすると、button1についてのソースコードを与えます。

+1

そのない[?イベントハンドラがすでに追加されている]の正確なDUPを(http://stackoverflow.com/questions/136975/has私はあなたの友人 – BugFinder

答えて

1

リフレクションとGetInvocationListメソッドを使用する必要があります。 button.Clickのハンドラの名前を取得し、リストにそれらを置くサンプルの下には:

public Form1() 
    { 
     InitializeComponent(); 

     this.button1.Click += Button1_Click; 
     this.button1.Click += Button1_Click1; 

     PropertyInfo propertyInfo = button1.GetType().GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); 
     EventHandlerList eventHandlerList = propertyInfo.GetValue(button1, new object[] { }) as EventHandlerList; 
     FieldInfo fieldInfo = typeof(Control).GetField("EventClick", BindingFlags.NonPublic | BindingFlags.Static); 

     var eventKey = fieldInfo.GetValue(button1); 
     var eventHandler = eventHandlerList[eventKey] as Delegate; 
     Delegate[] invocationList = eventHandler.GetInvocationList(); 

     var names = new List<string>(); 

     foreach (var handler in invocationList) 
     { 
      names.Add(handler.GetMethodInfo().Name); 
     } 
    } 

このアプローチは簡単にだけでなく、他のイベントにも適用することができます。あなたがテストしたいものは何でもイベントに"EventClick"を交換する必要があります。

FieldInfo fieldInfo = typeof(Control).GetField("EventClick", BindingFlags.NonPublic | BindingFlags.Static); 
+0

質問はwinformsとしてタグ付けされました。私は確信していませんが、私はあなたがwpfを指していると思います。 'System.Windows.Forms.Button'クラスで言及したフィールドを見つけることができません。とにかく、素晴らしい解決策。 –

+0

@RenéVogtいいえ、それは間違いなくwinformsソリューションです。 winforms enfironmentでテストされています。 – PiotrWolkowski

+0

私のソリューションのように、あなた自身の継承クラスは必要ないので、Upvoted。 –

0

これほど簡単ではありません。あるクラスで宣言されたイベントは、そのクラスのユーザーにのみaddremoveが公開されます。イベントの呼び出しリストには、クラス内からのみアクセスできます。

ですから、これを達成することができる一つの方法は、このような独自のMyButtonクラスを継承することです。だから私はbase.Clickイベントをラップし、余分なイベントで呼び出しリストを保存する新しいClickイベントを作成

public class MyButton : Button 
{ 
    private event EventHandler MyClick; 
    public new event EventHandler Click 
    { 
     add 
     { 
      MyClick += value; 
      base.Click += value; 
     } 
     remove 
     { 
      MyClick -= value; 
      base.Click -= value; 
     } 
    } 
    public Delegate[] GetClickHandlers() 
    { 
     return MyClick?.GetInvocationList(); 
    } 
} 

を。

Console.WriteLine(
    string.Join(Environment.NewLine, 
     button1.GetClickHandlers().Select(h => h.Method.Name))); 

をしかし、今、私はこのコードを見ていることは、おそらくストアは/別のリストにaddremoveに渡さvalue秒を削除できます。

あなたはよりも、このように、関連するハンドラの名前を取得することができますMyClickを使用する代わりに、アイデアは同じです。

あなたの主な問題はGetInvocationList()Button.Clickに電話できないことです。

+0

申し訳ありませんが、これは私の問題を解決することはできません。私はbutton1のようなコントロールがたくさんあるので、私は書き直すことはできませんそれらのそれぞれ。ありがとうすべて同じ〜 – SupperLee

関連する問題