2010-05-19 86 views
0

我正在嘗試爲我的表單上的每個控件添加一個事件處理程序。這個表單是一個簡單的信息框,它彈出,並點擊它上面的任何地方也會做同樣的事情(有點像Outlook的電子郵件通知器)。爲此,我寫了一個遞歸方法來爲每個控件添加一個MouseClick處理程序,如如下:如何通過名稱向事件添加事件處理程序?

private void AddMouseClickHandler(Control control, MouseEventHandler handler) 
{ 
    control.MouseClick += handler; 
    foreach (Control subControl in control.Controls) 
     AddMouseClickHandler(subControl, handler); 
} 

但是,如果我想添加一個處理所有MouseDownMouseUp事件,我不得不寫兩個方法。我確信有解決辦法,但我找不到它。我要像一個方法:

private void AddRecursiveHandler(Control control, Event event, EventHandler handler) 
{ 
    control.event += handler; 
    foreach (Control subControl in control.Controls) 
     AddRecursiveHandler(subControl, event, handler); 
} 

回答

3

你可以傳遞事件名字作爲一個字符串,然後使用反射來實現這一點,但是這將是相當難看(和減緩以及)。不幸的是,沒有其他方式將事件作爲參數傳遞給方法。

然而,你可以寫這個優雅的使用lambda功能。而不是寫函數中添加處理程序,您可以編寫調用各個控制lambda表達式的函數:

private void TraverseControls(Control control, Action<Control> f) 
{ 
    f(control); 
    foreach (Control subControl in control.Controls) 
     TraverseControls(subControl, f); 
} 

然後你就可以解決使用單個呼叫您最初的問題:

TraverseControls(form, ctl => { 
    ctl.MouseDown += handler; 
    ctl.MouseUp += handler); }); 

拉姆達表達式ctl => { .. }將針對樹中的每個控件和lambda表達式調用,您可以將控制器添加到控件的任何事件中。你也可以使用兩個調用來寫這個(第一個調用MouseDown,第二個調用MouseUp)。

與使用反射解決方案,這是更快,更安全。

+0

+1 Lambdas是一個整潔的解決方案。 – 2010-05-19 15:46:26

+0

這很好用!太糟糕了,你不能通過事件,壽。蘭姆達斯非常整潔;我必須更經常地記住他們。 – dlras2 2010-05-19 16:08:40

+0

多好的答案和代碼示例;謝謝,托馬斯! – BillW 2011-07-13 15:39:36

0

看起來你是一個很好的路徑上。如果你在你的窗體的MouseDown和MouseUp事件處理程序,你應該能夠連接到像你在

control.MouseClick += handler... 

已經這樣做只是添加,因爲簽名是一樣的,但動作不同的是,你會想要適當地處理。

control.MouseDown += YourFormsMouseDownHandler 
control.MouseUp += YourFormsMouseUpHandler 
0

如果您希望事件發生在任何地方,您不需要將事件添加到每個項目。只需將事件添加到父窗體(或面板,如果您只想讓面板中的項目響應),並且您在窗體內單擊的所有內容都將從父對象觸發事件。

+0

這是我真正想做的事,但它不起作用。有什麼選擇我必須設置?我只是想'pnlMain.MouseUp + = upHandler; pnlMain.MouseDown + = downHandler;' – dlras2 2010-05-19 16:03:27

+0

我不是100%確定,但我想如果一個子控件處理一個事件,它將不會調用父項事件。 – 2010-05-19 17:08:00

+0

有沒有辦法告訴孩子控制*不是*來處理這個事件,這樣父母會呢? – dlras2 2010-05-19 19:39:07

相關問題