tags:

views:

248

answers:

5

Hi I am catching a KeyPress-Event to check for certain kinds of allowed values. To be able to delete I am using following code before the actual check

if (e.KeyChar == (char)Keys.Delete || e.KeyChar == (char)Keys.Back)
{
   return;
}
...actual check for only digits or whatever

The problem is that e.KeyChar == (char)Keys.Delete is also true when I hit the period on my keyboard.

How can this be? And what could I do about it?

Thanks

+3  A: 

Maybe you should compare with e.KeyCode instead. It's more precise and you won't need to convert Keys.Delete and Keys.Back to a char.

Meta-Knight
The KeyPressEventArgs e doesnt have a property KeyCode (only KeyChar).I was wondering about this when I wrote the code anyways since the Keys class only has KeyCodes :-/
lostiniceland
That's right, you'd have to use KeyDown instead of KeyPress. I forgot about this.
Meta-Knight
A: 

Perhaps it would work in your application to instead capture the KeyDown event.

You could then do something such as:

if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back)
{
   return;
}

Note that KeyCode is part of the args passed for KeyDown and KeyUp but not for KeyPress.

itsmatt
same problem as on Meta-Knights answer. Thanks anyway
lostiniceland
A: 

KeyPress works with characters, KeyDown works with keys. As both Meta-Knight and itsmatt suggested, you should use KeyDown if you want to detect keys.

If you look at the arithmetic keyboard, you will notice that Del and . are on the same key.

Anax
+4  A: 

From MSDN documentation on the Keys enumeration:

The Keys class contains constants for processing keyboard input. The members of the Keys enumeration consist of a key code and a set of modifiers combined into a single integer value. In the Win32 application programming interface (API) a key value has two halves, with the high-order bits containing the key code (which is the same as a Windows virtual key code), and the low-order bits representing key modifiers such as the SHIFT, CONTROL, and ALT keys.

Converting these constants to char is meaningless, since you will lose valuable information and the constant values do not correspond to ASCII character codes.

From MSDN concerning the KeyChar property of KeyPressEventArgs:

You cannot get or set the following keys (...) INSERT and DELETE (...)

KeyChar returns the char value (ASCII character code) corresponding to pressed key, not its (raw) key code. Therefore you cannot detect various special keys and cannot compare the value to the Keys enumeration constants.

Use the KeyCode property of KeyEventArgs instead. Since it is of type Keys, not char, it is well suited for your purpose. In order to access this information, you will have to handle the KeyDown event instead of the KeyPress event.

By the way, according to the MSDN page on the Control KeyPress event, this event is not raised for non-character keys at all:

The KeyPress event is not raised by noncharacter keys; however, the noncharacter keys do raise the KeyDown and KeyUp events.

Ferdinand Beyer
Thanks for that very precise answer. Still I am wondering why .Net is not consistent in this.
lostiniceland
Actually I think that the **KeyPress** event is just for convenience when all you need is the **char** code. **KeyDown** is triggered before **KeyPress** and is the more generic event.
Ferdinand Beyer
A: 
//If you can change the event handler for the control 
//that you are looking at catching the keys.  
//In the example below textBox1 is using 
//setting the KeyEventHandler to be KeyDownEvents Method...  
//this has the KeyCode properties...

this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.KeyDownEvents);
//This is the code in the event...
 private void KeyDownEvents(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.BrowserBack)
            {
                MessageBox.Show(e.KeyCode.ToString());
            }
        }