2010-05-19 48 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

相关问题