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);
}
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.
You can use reflection to hook up to events. Take a look at this article on MSDN
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
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.