2013-07-30 45 views
1

我期待添加日誌語句每WinForms的按鈕點擊,用戶點擊,和理想,父窗體的indentifier(如標題欄)。我看到帖子記錄所有鼠標點擊,但我只是記錄按鈕點擊感興趣。我已經閱讀接受的答案here並適於它:登錄贏得所有按鈕點擊窗體應用程序

public class ButtonLogger 
    { 
     private static readonly ILog Logger = LogManager.GetLogger(typeof(ButtonLogger)); 

     public static void AttachButtonLogging(Control.ControlCollection controls) 
     { 
      foreach (var button in controls.OfType<Button>()) 
      { 
       button.Click += LogButtonClick; 
      } 
     } 

     private static void LogButtonClick(object sender, EventArgs eventArgs) 
     { 

      Button button = sender as Button; 
      Logger.InfoFormat("Button clicked: {0} ({1})", button.Text, button.Parent.Text); 
     } 
    } 

此類的形式用於在構造結束時,例如:

ButtonLogger.AttachButtonLogging(this.Controls); 

我面臨的問題是,Controls屬性似乎沒有對我的按鈕的引用。大概這是因爲按鈕不是直接添加到窗體,而是另一個在Controls屬性中的控件。但是,控件屬性只包含一個控件,一個ToolStrip。

有沒有一種方法,我可以利用所有按鈕的形式,不管他們的父容器的?我的最終目標是到日誌語句添加到我的按鈕,所以如果這可以實現,除了按鈕單擊事件方法的一些其他的方式,然後我打開那以及

回答

4

我相信你需要搜索按鈕遞歸:

public static void AttachButtonLogging(Control.ControlCollection controls) 
{ 
    foreach (var control in controls.Cast<Control>()) 
    { 
     if (control is Button) 
     { 
      Button button = (Button)control; 
      button.Click += LogButtonClick; 
     } 
     else 
     { 
      AttachButtonLogging(control.Controls); 
     } 
    } 
} 
+2

有中,我們有一個'TabControl'有的'Buttons'一些'TabPage'的情況,我們在'TabControl.TabPages'看。我遇到過這個問題,但是如果這不是OP的情況,這段代碼就可以正常工作。 –

+0

@KingKing謝謝,非常好的音符。坦率地說,我認爲tab頁面會出現在TabControl的控件中。奇怪的設計! –

+0

這是否已知會在構建表單時導致任何性能問題?雖然這是遞歸,但它應該很輕,因爲在特定的表單上有少量控件(最多20個)。另外,因爲在「真實」事件附加到按鈕後附加了這些事件,所以它不應該延遲單擊按鈕時想要發生的實際處理。 –

0

有一件事你可以考慮是創建標準Button類的子類,並讓自己的按鈕做了記錄。當然,你不得不四處使用應用程序中的所有按鈕來替代你自己的實現,但應該可以通過全局搜索+替換來完成。

下面是一個示例實現:

public class LoggerButton : Button 
{ 
    private static readonly ILog Logger = LogManager.GetLogger(typeof(LoggerButton)); 

    protected override void OnClick(EventArgs e) 
    { 
     base.OnClick(e); 
     Logger.InfoFormat("Button clicked: {0} ({1})", this.Text, this.Parent.Text); 
    } 
} 
+0

這使得設計師的工作更具挑戰性。您必須創建一個自定義工具箱托盤,並使用自定義按鈕類而不是內置的托盤類。不過,這是一個可以肯定的選擇,但也許是對繼承的濫用。 –

+0

@StealthRabbi真的嗎?我從來沒有必要爲我的自定義控件做任何特殊的事情,以顯示在Visual Studio工具箱中。但是,我會同意這有點冒險。 –