Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One event handler for all controls on the form

I have a problem with setting the same event handler for all controls on the form. I want to handle pressed f5-f7 buttons uniformly in my application, so I try to register the same event handler for all controls on the form. I inserted

foreach (System.Windows.Forms.Control cont in this.Controls)
                cont.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyPress);

in InitializeComponent() function just before automatically generated ResumeLayout/PerformLayout calls. Don't mind the the name MainForm_KeyPress, it's actually a KeyDown event handler now.

I also tried to insert the code in my init() function which is called from constructor. But result was the same: the event does not occur when I press keys. Focus is on one of form's buttons.

But if I implement the handler for one of the buttons using design tool (copy function name to KeyPress event field), the event raises correctly if the button is in focus.

Any ideas why foreach didn't work?

like image 674
HtonS Avatar asked Sep 14 '11 02:09

HtonS


2 Answers

MSDN says you can do with with setting KeyPreview to true.

like image 54
Candide Avatar answered Sep 29 '22 13:09

Candide


Maybe you need to recurse and register it for the child controls of each control you encounter, on down the tree?

First thing I'd do upon having this problem is put { } around the registration and output "now registering for " + the control name. That way you can watch and see how many controls are being registered and what they are. Maybe it's just the main panel, and the subcontrols process the key down? I've had troubles with key press event handlers when working in a dockmanager as well, the dockmanager was handling the keyboard at another level and routing the event to the specific child control it thought should get it.

If you still don't figure it out, next thing I'd do is wire up the form's events, or maybe even monitor the WM_ windows message events. At some point the WM_ is translated into a .NET event by code, and this can be implemented in ways you don't expect, and hijacked by third-party controls, etc. The operating system must be routing the WM_ events to your process, so track them with pass-through event handlers that log what goes through.

I forget exactly how it works but when processing an event like a keypress, you can either return a bool or set a flag on the event saying you've handled it, and in the dockmanager implementation I saw if you said you handled it, the loop that was passing the event to child controls would stop, enforcing the idea that only one action should be triggered by the keyboard event.

like image 28
rice Avatar answered Sep 29 '22 12:09

rice