views:

376

answers:

2

I wonder what the Form.KeyPreview property actually is good for? Why do it exist and what do I "risk" by setting it to true? I guess it must have some negative effect - otherwise it shouldn't exist at all (or at least be true by default)?

EDIT: I know perfectly well what it does. I'm asking why. Why do I have to set it to true in order to make the keyboard events fire? Why doesn't the keyboard events always fire for a form. What isn't just that the standard behavior?

The particular reason I ask is: I have just set KeyPreview = true in the base form of my app, which all other forms inherit from. Am I in for any nasty surprise?

A: 

From MSDN

When this property is set to true, the form will receive all KeyPress, KeyDown, and KeyUp events. After the form's event handlers have completed processing the keystroke, the keystroke is then assigned to the control with focus. For example, if the KeyPreview property is set to true and the currently selected control is a TextBox, after the keystroke is handled by the event handlers of the form the TextBox control will receive the key that was pressed. To handle keyboard events only at the form level and not allow controls to receive keyboard events, set the KeyPressEventArgs.Handled property in your form's KeyPress event handler to true.

You can use this property to process most keystrokes in your application and either handle the keystroke or call the appropriate control to handle the keystroke. For example, when an application uses function keys, you might want to process the keystrokes at the form level rather than writing code for each control that might receive keystroke events.

Basically when you set it to true, your form can process key events as well as your controls.

E.G User presses K key, the forms event handlers are called(Key Down, Key Up, Key Pressed) and then the event handlers on the currently active control are called.

EDIT: No there are no disadvantages or nasty suprises. The only thing i can think of is a very tiny performance decrease as it needs to check for event handles on the form for each KeyDown,KeyUp, KeyPressed. Apart from that unless you're adding event handlers to the form, and doing something that might cause problems. you're perfectly fine. If you don't need to globally handle key events except on controls then I would suggest you leave this as false to prevent the extra checks. On modern PC's this wouldnt have a visible difference.

LnDCobra
Completely correct. Unfortunately it doesn't in any way answer what I asked.
danbystrom
+4  A: 

Form.KeyPreview is a bit of an anachronism, inherited from the Visual Basic object model for form design. Back in the VB6 days, you needed KeyPreview to be able to implement short-cut keystrokes. That isn't needed anymore in Windows Forms, overriding the ProcessCmdKey() is the better solution:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
  if (keyData == (Keys.Control | Keys.F)) {
    DoSomething();   // Implement the Ctrl+F short-cut keystroke
    return true;     // This keystroke was handled, don't pass to the control with the focus
  }
  return base.ProcessCmdKey(ref msg, keyData);
}

But KeyPreview was supported to help the legion of VB6 programmers switch to .NET back in the early 2000's. The point of KeyPreview or ProcessCmdKey() is to allow your UI to respond to shortcut keystrokes. Keyboard messages are normally sent to the control that has the focus. The Windows Forms message loop allows code to have a peek at that message before the control sees it. That's important for short-cut keys, implementing the KeyDown event for every control that might get the focus to detect them is very impractical.

Setting KeyPreview to True doesn't cause problems. The form's KeyDown event will run, it will only have an affect if it has code that does something with the keystroke.

Hans Passant
+1 for ProcessCmdKey.
Adam Neal