Up, Down, Left and Right arrow keys do not trigger KeyDown event

169,251

Solution 1

    protected override bool IsInputKey(Keys keyData)
    {
        switch (keyData)
        {
            case Keys.Right:
            case Keys.Left:
            case Keys.Up:
            case Keys.Down:
                return true;
            case Keys.Shift | Keys.Right:
            case Keys.Shift | Keys.Left:
            case Keys.Shift | Keys.Up:
            case Keys.Shift | Keys.Down:
                return true;
        }
        return base.IsInputKey(keyData);
    }
    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);
        switch (e.KeyCode)
        {
            case Keys.Left:
            case Keys.Right:
            case Keys.Up:
            case Keys.Down:
                if (e.Shift)
                {

                }
                else
                {
                }
                break;                
        }
    }

Solution 2

I was having the exact same problem. I considered the answer @Snarfblam provided; however, if you read the documentation on MSDN, the ProcessCMDKey method is meant to override key events for menu items in an application.

I recently stumbled across this article from microsoft, which looks quite promising: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx. According to microsoft, the best thing to do is set e.IsInputKey=true; in the PreviewKeyDown event after detecting the arrow keys. Doing so will fire the KeyDown event.

This worked quite well for me and was less hack-ish than overriding the ProcessCMDKey.

Solution 3

I'm using PreviewKeyDown

    private void _calendar_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e){
        switch (e.KeyCode){
            case Keys.Down:
            case Keys.Right:
                //action
                break;
            case Keys.Up:
            case Keys.Left:
                //action
                break;
        }
    }

Solution 4

See Rodolfo Neuber's reply for the best answer


(My original answer):

Derive from a control class and you can override the ProcessCmdKey method. Microsoft chose to omit these keys from KeyDown events because they affect multiple controls and move the focus, but this makes it very difficult to make an app react to these keys in any other way.

Solution 5

I had a similar issue when calling the WPF window out of WinForms.

var wpfwindow = new ScreenBoardWPF.IzbiraProjekti();
    ElementHost.EnableModelessKeyboardInterop(wpfwindow);
    wpfwindow.Show();

However, showing window as a dialog, it worked

var wpfwindow = new ScreenBoardWPF.IzbiraProjekti();
    ElementHost.EnableModelessKeyboardInterop(wpfwindow);
    wpfwindow.ShowDialog();

Hope this helps.

Share:
169,251

Related videos on Youtube

Martin Delille
Author by

Martin Delille

Scout/Lead developer/Teacher/UX at https://www.lylo.tv

Updated on July 05, 2022

Comments

  • Martin Delille
    Martin Delille almost 2 years

    I am building an application where all the key input must be handled by the windows itself.

    I set tabstop to false for each control witch could grab the focus except a panel (but I don't know if it has effect).

    I set KeyPreview to true and I am handling the KeyDown event on this form.

    My problem is that sometimes the arrow key aren't responsive anymore:

    • The keydown event is not fired when I pressed only an arrow key.

    • The keydown event is fired if I press an arrow key with the control modifier.

    Have you an idea why my arrow key suddenly stop firing event?

    • ChrisF
      ChrisF over 14 years
      Can you post the code that you've got in your KeyDown event handler.
    • Maxim Zaslavsky
      Maxim Zaslavsky over 14 years
      Maybe this will help you? stackoverflow.com/questions/902767/…
    • snarf
      snarf over 14 years
      @ Maxim, I'm pretty sure if a window contains any child controls, the key events for arrow keys will be suppressed. The question you linked to dealt with a form with no controls. Daniel Waltrip's problem wasn't really the same.
    • Maxim Zaslavsky
      Maxim Zaslavsky over 14 years
      @Snarfblam I'm not sure I understand - why would that be an issue here?
    • sam yi
      sam yi over 12 years
  • Martin Delille
    Martin Delille over 14 years
    It seems that ProcessCmdKey is the only way to handle the keyboard accurately. Thanks!
  • vpalmu
    vpalmu almost 12 years
    This answer is dead wrong. If I hadn't already overridden OnKeyDown from some base control that already handled the arrow keys (to change the behavior) I would not have known this and implemented it the hard way. See alpha's answer below.
  • zionpi
    zionpi almost 11 years
    Even alpha's answer doesn't work for my situation,but Snarfblam's does.Thank you!
  • Paul Kapustin
    Paul Kapustin about 10 years
    Worked beautifully for me, no need to inherit/override
  • AStackOverflowUser
    AStackOverflowUser almost 10 years
    This should be the chosen answer, it is way cleaner and it works wonderfully.
  • T30
    T30 almost 10 years
    Yeah it works! The answer is quite clear, but I want to specify that the IsInputKey is in e class: e.IsInputKey=true.
  • T30
    T30 almost 10 years
    (what does it happens if you do it for all keys without detecting the arrows?)
  • Iman
    Iman about 9 years
    Note that all the tab stop for controls, should be false.(I faced with such a problem :D)
  • Dave Cousineau
    Dave Cousineau over 7 years
    this worked extremely well, thanks. behaves exactly like I would expect a key event to behave.
  • Ghigo
    Ghigo almost 7 years
    This is actually an hack. Check Rodolfo Neuber answer for correct answer.
  • google dev
    google dev almost 5 years
    @T30 You will lose the Alt for the menus
  • Joe Gayetty
    Joe Gayetty over 4 years
    THIS should be the accepted answer!!! Just use the PreviewKeyDown event. Works with no hacking required. Couldn't be cleaner or simpler.