6

With the code below, the Left and Right arrow keys function as expected, but the up and down arrows are not recognized (stepping through it, the first two conditions are met where appropriate, but the second two never are):

private void textBox1_KeyDown(object sender, KeyEventArgs e) {
    TextBox tb = (TextBox)sender;

    if (e.KeyCode.Equals(Keys.Left)) {
        SetFocusOneColumnBack(tb.Name);
        e.Handled = true;
        return;
    }
    if (e.KeyCode.Equals(Keys.Right)) {
        SetFocusOneColumnForward(tb.Name);
        e.Handled = true;
        return;
    }
    if (e.KeyCode.Equals(Keys.Up)) {
        SetFocusOneRowUp(tb.Name);
        e.Handled = true;
        return;
    }
    if (e.KeyCode.Equals(Keys.Down)) {
        SetFocusOneRowDown(tb.Name);
        e.Handled = true;
        return;
    }
}

Why would this be, and how can I fix it?

UPDATE

Here's what I see when I hover over e.Keycode while stepping through. If I pressed

  • ...Left arrow key, I see: e.KeyCode = "LButton | MButton | Space"
  • ...Right arrow key, I see: e.KeyCode = "LButton | RButton | MButton | Space"
  • ...Up arrow key, I see: e.KeyCode = "RButton | MButton | Space"
  • ...Down arrow key, I see: e.KeyCode = "Backspace | Space"

This has got me baffled (what it's showing me), but on keyleft and keyright, my code is entered - it never is for keyup and keydown, no matter how hard I clench my teeth.

Alain
  • 26,663
  • 20
  • 114
  • 184
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • 1
    Put a break-point at the start of your event handler. Is it even getting called for up and down keys? If not, something else is getting the event and calling `e.Handled = true` before this handler gets the chance. – Alain May 09 '12 at 16:57
  • Yes, I mention stepping through it in my original post. – B. Clay Shannon-B. Crow Raven May 09 '12 at 17:09
  • 1
    Well, as you're stepping through it, what's the value of `e.KeyCode` for those two cases? – Alain May 09 '12 at 17:12
  • Good question; answered above (updated my post) – B. Clay Shannon-B. Crow Raven May 09 '12 at 17:18
  • Do you by any chance use a fancy [Logitech](http://bytes.com/topic/net/answers/852581-c-win-keycode-numbers-string) keyboard? Or are you coding for a [mobile platform](http://www.pcreview.co.uk/forums/hardwarebutton-class-doesnt-work-red-and-green-telefon-buttons-t2610671.html)? – Alain May 09 '12 at 17:36
  • I'm also thinking that something else that handled this event might have tried to do a bad bitwise combination of its member values and ended up modifying it. – Alain May 09 '12 at 17:44
  • As a matter of fact, it IS a Logitech keyboard. Whether it's fancy or not, I don't know - I hadn't even paid any attention to what brand it was until you asked and I looked. BUT, it's solved now (by using the PreviewKeyDown event). – B. Clay Shannon-B. Crow Raven May 09 '12 at 18:00

4 Answers4

4

Windows captures certain keys for UI navigation before they every get sent to your form. If you want to override this behavior you need to overload the IsInputKey method (and subclass the text field):

    protected override bool IsInputKey(Keys keyData)
    {
        if (keyData == Keys.Right)
            return true;
        return base.IsInputKey(keyData);
    }
Hampus Nilsson
  • 6,692
  • 1
  • 25
  • 29
3

I find that using the PreviewKeyDown does work (I had to remove the "e.Handled = true" code, as it doesn't apply in the PreviewKeyDown event):

private void textBoxQH1_PreviewKeyDown(object sender,   PreviewKeyDownEventArgs e) {
    TextBox tb = (TextBox)sender;

    if (e.KeyCode.Equals(Keys.Up)) {
        SetFocusOneRowUp(tb.Name);
        return;
    }
    if (e.KeyCode.Equals(Keys.Down)) {
        SetFocusOneRowDown(tb.Name);
        return;
    }
}

So, three different events were needed to handle the various keys I was looking for: KeyPress for regular characters, KeyDown for non-characters (left and right arrow keys) and this one (PreviewKeyDown) for the up and down arrow keys.

B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • With `PreviewKeyDown`, you're getting to the `KeyCode` before anything else gets a chance to modify it. My guess is that somewhere else in the code something is doing a bad bitwise combination and butchering the code before it gets to the KeyDown event. Also note that you could just as easily handle the `Keys.Left` and `Keys.Right` here in the `PreviewKeyDown` event, which will mean you only need 2 events instead of 3. – Alain May 09 '12 at 17:48
  • 1
    I think Hampus Nilsson answered the question as to why left and right were processing correctly, yet up and down were not. That's what gave me the idea to try to cut Windows off at the pass by intercepting their interception before they could intercept. – B. Clay Shannon-B. Crow Raven May 09 '12 at 18:01
  • 1
    +1 for "Intercepting their interception before they could intercept" – Alain May 09 '12 at 18:15
1

You can use this code:

private void TextBox1_KeyDown(object sender, KeyEventArgs e)
{
    switch (e.KeyCode)
    {
        case Keys.Up:
            //Do stuff
            break;
        case Keys.Down:
            //Do stuff
            break;
        case Keys.Left:
            //Do stuff
            break;
        case Keys.Right:
            //Do stuff
            break;
    }
}
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
1

Well too late for the party but if anyone is interested, use e.KeyValue instead, as an example, e.KeyValue for left arrow key is 37 and for right arrow key 39 and so on.

YazX
  • 444
  • 4
  • 12