我正在尝试为表单上的每个控件添加一个事件处理程序。表单是一个简单的信息框,弹出,点击它的任何地方都做同样的事情(有点像Outlook的电子邮件通知程序。)为此,我编写了一个递归方法来添加MouseClick
处理程序每个控件如下:
private void AddMouseClickHandler(Control control, MouseEventHandler handler)
{
control.MouseClick += handler;
foreach (Control subControl in control.Controls)
AddMouseClickHandler(subControl, handler);
}
但是,如果我想为所有MouseDown
和MouseUp
事件添加处理程序,我必须再编写两个方法。我确定有办法解决这个问题,但我找不到它。我想要一个像这样的方法:
private void AddRecursiveHandler(Control control, Event event, EventHandler handler)
{
control.event += handler;
foreach (Control subControl in control.Controls)
AddRecursiveHandler(subControl, event, handler);
}
答案 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)
如果您希望事件在任何地方发生,则无需将事件添加到每个项目。只需将一个事件添加到父窗体(或面板,如果您只想要面板中的项目进行响应),您在该窗体中单击的所有内容都将从父对象触发事件。