14

I need to disable changing focus with arrows on form. Is there an easy way how to do it?

Thank you

ire_and_curses
  • 68,372
  • 23
  • 116
  • 141
MartyIX
  • 27,828
  • 29
  • 136
  • 207

4 Answers4

18

Something along the lines of:

    private void Form1_Load(object sender, EventArgs e)
    {
        foreach (Control control in this.Controls)
        {
            control.PreviewKeyDown += new PreviewKeyDownEventHandler(control_PreviewKeyDown);
        }
    }

    void control_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.Left || e.KeyCode == Keys.Right)
        {
            e.IsInputKey = true;
        }
    }
andynormancx
  • 13,421
  • 6
  • 36
  • 52
  • 1
    Works perfect. Thank you! Just short note for other people: foreach (Control control in this.Controls) does not contain all controls - you may have containers (e.g., system.windows.forms.panel) on form. – MartyIX Aug 23 '09 at 11:42
  • Wouldn't have thought of that, but that seems to completely work. (My goal was to conditionally disable Enter, but same idea.) Thanks! – neminem Aug 28 '13 at 23:40
  • Ah thank you! The key was PreviewKeyDown event instead of KeyDown event. I was trying to solve the issue under KeyDown event but once I set space key as input key it solved. Now my buttons don't get clicked with space :) – Shino Lex Nov 09 '20 at 13:21
5

I've ended up with the code below which set the feature to EVERY control on form:

(The code is based on the one from andynormancx)



private void Form1_Load(object sender, EventArgs e)
{
    SetFeatureToAllControls(this.Controls);    
}

private void SetFeatureToAllControls(Control.ControlCollection cc)
{
    if (cc != null)
    {
        foreach (Control control in cc)
        {
            control.PreviewKeyDown += new PreviewKeyDownEventHandler(control_PreviewKeyDown);
            SetFeatureToAllControls(control.Controls);
        }
    }
}

void control_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.Left || e.KeyCode == Keys.Right)
    {
        e.IsInputKey = true;
    }
}
MartyIX
  • 27,828
  • 29
  • 136
  • 207
1

You should set KeyPreview to true on the form. Handle the KeyDown/KeyUp/KeyPress event and set the e.Handled in the eventhandler to true for the keys you want to be ignored.

Irshad
  • 3,071
  • 5
  • 30
  • 51
Henri
  • 5,065
  • 23
  • 24
  • 1
    That approach doesn't seems to work, there is no e.Handled on the PreviewKeyDownEventArgs – andynormancx Aug 23 '09 at 11:15
  • e.Handled exists but in method: private void Form1_KeyUp(object sender, KeyEventArgs e), KeyDown etc. I have problems with this approach too. I'll try it on clean project. – MartyIX Aug 23 '09 at 11:20
  • 1
    Yes it exists in the KeyDown event, but setting it doesn't help, the navigation has already happened by that point. – andynormancx Aug 23 '09 at 11:34
  • I wasn't sure when the navigation was made. The advice below works great. – MartyIX Aug 23 '09 at 11:39
1

I tried this aproach, where the form handles the preview event once. It generates less code than the other options.

Just add this method to the PreviewKeyDown event of your form, and set the KeyPreview property to true.

private void form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    switch (e.KeyCode)
    {
        case Keys.Up:
        case Keys.Down:
        case Keys.Left:
        case Keys.Right:
            e.IsInputKey = true;
            break;
        default:
            break;
    }
}
Taryn
  • 242,637
  • 56
  • 362
  • 405
  • 1
    Hi carlos. I wanted to use your shorter version, but when I tested it, it did not do what it should unfortunately.. (and I did remember to set `Form.KeyPreview=true` of course). Only when I added the foreach() in Form_Load, then the behavior changed.. Have you tested it? – spaceman Feb 13 '16 at 06:00
  • 1
    this does not work if the form contains more than one level of container hierarchies. – oopsdazie May 17 '19 at 21:04