7

I have a C# winform, on which I have 1 button.
Now, when I run my application, the button gets focus automatically.

The problem is KeyPress event of my form does not work because the button is focused.

I have tried this.Focus(); on FormLoad() event, but still the KeyPress event is not working.

Amar Palsapure
  • 9,590
  • 1
  • 27
  • 46
Javed Akram
  • 15,024
  • 26
  • 81
  • 118

5 Answers5

11

You need to override the ProcessCmdKey method for your form. That's the only way you're going to be notified of key events that occur when child controls have the keyboard focus.

Sample code:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    // look for the expected key
    if (keyData == Keys.A)
    {
        // take some action
        MessageBox.Show("The A key was pressed");

        // eat the message to prevent it from being passed on
        return true;

        // (alternatively, return FALSE to allow the key event to be passed on)
    }

    // call the base class to handle other key events
    return base.ProcessCmdKey(ref msg, keyData);
}

As for why this.Focus() doesn't work, it's because a form can't have the focus by itself. A particular control has to have the focus, so when you set focus to the form, it actually sets the focus to the first control that can accept the focus that has the lowest TabIndex value. In this case, that's your button.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • 3
    Beware that ProcessCmdKey() is *not* a substitute for KeyPress. There's a big difference between virtual keys and the characters that they get translated to. There is no good way to get the equivalent of KeyPress. – Hans Passant Mar 31 '11 at 13:07
5

Try setting the Form's KeyPreview property to True.

John Koerner
  • 37,428
  • 8
  • 84
  • 134
  • Ok fine, but when my button as well has keyPress event, then both keyPress events will be fired. – Javed Akram Mar 31 '11 at 12:08
  • This isn't really a good solution. It won't work for all possible keys, it doesn't prevent the key event from being stolen by the control, and it's more of an old school VB 6 way of handling things. Overriding `ProcessCmdKey` is the customary approach. – Cody Gray - on strike Mar 31 '11 at 12:13
  • @CodyGray: However, this is a suitable alternative when the goal is to receive `KeyPress` events. Obviously one needs to be careful when using it, but it is often easier/simpler than trying to map specific key events to characters. – Peter Duniho Jun 18 '17 at 18:58
1

Set keyPreview = true on main form

0

I had this same problem and I know this question was answered long ago, but my solution to this problem came from another stack overflow question in which my only button grabbed and kept focus. I accepted the users advice and created a button which couldn't get focus.

Maybe someone will find this useful:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace I2c_Programmer {
    class NoSelectButton : Button{

            public NoSelectButton() {

            SetStyle(ControlStyles.Selectable, false);

        }
    }
}

Go into your designer, where the button is created and switch out the new System...button with your new class "new NoSelectButton();"

C4F
  • 662
  • 7
  • 18
0

I would use one of the following:

  1. Set the TabIndex property of the button to 0.

  2. Set the IsDefault property of the button to true - So, It will be fired when pressing the ENTER key.

Tal Yaari
  • 463
  • 6
  • 15
  • Hmm, he says that the button *has* the focus when the form is loaded, so I can only assume that it is already responding when the user presses the Enter (or Space) key. The question doesn't specify a particular key that he wants to catch; I suspect that it's probably not Enter. – Cody Gray - on strike Mar 31 '11 at 12:15