2016-04-26 17 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環境中測試。 – PiotrWolkowski

+0

好的。 Upvoted,因爲你不需要像我的解決方案一樣擁有自己的繼承類。 –

0

這並不容易。在一個類中聲明的事件僅向該類的用戶公開addremove。只能從類內部訪問事件的調用列表。

所以,你可以做到這一點的一種方式是繼承自己MyButton類是這樣的:

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(); 
    } 
} 

所以我創建了一個新的Click事件封裝了base.Click事件,並存儲在一個額外的事件調用列表。

可以比得到的相關處理程序的名稱是這樣的:

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

但現在,我看到這個代碼,你很可能存儲/刪除value秒後,以addremove在一個單獨的列表而不是使用MyClick,但這個想法是一樣的。

您的主要問題是,您不能致電 GetInvocationList()

+0

很抱歉,這不能解決我的問題。因爲我有太多的控制像button1,我不能重寫每個人。謝謝你們一樣〜 – SupperLee