0

How can I convert a KeyPressEventArgs.KeyChar to Key?

Casting does not work... see here:

private void textBox_console_KeyPress(object sender, KeyPressEventArgs e)
{

    var key_char = e.KeyChar.ToLower(); //w

    var pressed_key = (Key)(key_char); //RightCtrl
    var key_check = Keyboard.IsKeyDown(pressed_key);
}

If in this example, I press w, which has a value of 119, key_check will be false because (Key)(e.KeyChar) will evaluate to RightCtrl.

I need to convert the e.KeyChar to a System.Windows.Input.Key.W, which has a value of 66.

pookie
  • 3,796
  • 6
  • 49
  • 105
  • 3
    If you need to work with key codes, use the KeyDown event instead. There is no direct relation between keycodes and characters, as many keys do not correspond to a character at all, and many are combinations (as capital A is decoded from Shift and Keys.A) – Cee McSharpface Jan 13 '18 at 13:41
  • As noted in @dlatikay's comment, you cannot reliably map from a character to a key. The key code describes the physical key that was pressed, and since some keys don't produce characters, while some characters require multiple key presses to generate, and all of this can even change according to the current _state_ of the keyboard (e.g. caps-lock), there just is not a one-to-one mapping. See proposed duplicate, which recommends using `KeyDown` (again, as in the first comment above). – Peter Duniho Jan 13 '18 at 23:44

1 Answers1

1

You could exploit the fact that the lower word of the Keys enumeration encodes the keycode, which is designed to correspond to the ASCII character codes of the capital letters.

For example, Keys.A has a value of 0x41 (decimal 65), which is (char)'A'.

So basically, you could do:

var key = (Keys)e.KeyChar.ToUpper();

which will work for the umodified, non-accented latin letters. For the numbers, you would have to decide whether you would rather map back to the numpad keys, or the horizontally arranged ones. The latter are also mapped to their ASCII codes, for example Keys.D0 is 0x30, decimal 48, (char)'0'.

You could also determine whether the keychar is lower case or upper case, and encode that into the shift bit of the key code modifier:

if(Char.IsUpper(e.KeyChar)) key |= Keys.Shift

Finally, use this answer based on this function to map the System.Windows.Forms.Keys value to the System.Windows.Input.Key you need:

var pressed_key = KeyInterop.KeyFromVirtualKey((int)key);

But this is no valid solution for the whole range of characters, let alone different alphabets, and I think what you really want to do is to subscribe to the KeyDown event instead, which tells you the key codes right away.

Cee McSharpface
  • 8,493
  • 3
  • 36
  • 77