How can I add an event handler to an event by name?

匆匆过客 提交于 2020-01-07 04:56:08

问题


I'm attempting to add an event handler for every control on my form. The form is a simple info box which pops up, and clicking anywhere on it does the same thing (sort of like Outlook's email notifier.) To do this, I've written a recursive method to add a MouseClick handler to each control, as follows:

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

However, if I wanted to add a handler for all of the MouseDown and MouseUp events, I'd have to write two more methods. I'm sure there's a way around this, but I can't find it. I want a method like:

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

回答1:


You could pass the event name as a string and then use Reflection to implement this, but that would be quite ugly (and slow as well). Unfortunately, there is no other way to pass events as arguments to a method.

However, you can write this elegantly using lambda functions. Instead of writing function to add handler, you can write a function that calls a lambda expression for every control:

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

Then you can solve your original problem using a single call:

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

The lambda expression ctl => { .. } will be called for every control in the tree and inside the lambda expression, you can add handlers to any events of the control. You could also write this using two calls (adding handlers to MouseDown in the first one and to MouseUp in the second one).

Compared to solution using Reflection, this is faster and safer.




回答2:


You can use reflection to hook up to events. Take a look at this article on MSDN




回答3:


It looks like you are on a good path. If you have an event handler in your FORM's MouseDown and MouseUp, you should just be able to attach to that like you already do in your

control.MouseClick += handler... 

just add since the signature is the same, but the action is different, you'll want to handle appropriately.

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



回答4:


If you want the event to happen everywhere you do not need to add the event to every item. just add a event to the parent form (or panel if you want just the items in a panel to respond) and everything you click inside that form will fire the event from the parent object.



来源:https://stackoverflow.com/questions/2866936/how-can-i-add-an-event-handler-to-an-event-by-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!