如何按名称向事件添加事件处理程序?

时间:2010-05-19 15:28:00

标签: c# .net events controls event-handling

我正在尝试为表单上的每个控件添加一个事件处理程序。表单是一个简单的信息框,弹出,点击它的任何地方都做同样的事情(有点像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);
}

4 个答案:

答案 0 :(得分:3)

您可以将事件名称作为字符串传递,然后使用Reflection来实现它,但这将非常丑陋(并且也很慢)。不幸的是,没有其他方法可以将事件作为参数传递给方法。

但是,您可以使用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); });

将为树中的每个控件和lambda表达式内部调用lambda表达式ctl => { .. },您可以向控件的任何事件添加处理程序。您也可以使用两个调用来编写此代码(在第一个调用中将处理程序添加到MouseDown,在第二个调用中添加到MouseUp)。

与使用Reflection的解决方案相比,这更快更安全。

答案 1 :(得分:1)

您可以使用反射来连接事件。看看this article on MSDN

答案 2 :(得分:0)

看起来你走的很好。如果你的FORM的MouseDown和MouseUp中有一个事件处理程序,你应该能够像你已经在你的

那样附加到那个
control.MouseClick += handler... 

只是添加,因为签名是相同的,但行动是不同的,你需要妥善处理。

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

答案 3 :(得分:0)

如果您希望事件在任何地方发生,则无需将事件添加到每个项目。只需将一个事件添加到父窗体(或面板,如果您只想要面板中的项目进行响应),您在该窗体中单击的所有内容都将从父对象触发事件。