KeyDown event - how to easily know if the key pressed is numeric? - c#

I am currently handling the KeyDown event of a DataGridView control.
One of the columns is filled by calculated values and I want the user to be able to override the cell value if they want.
When the user presses a numeric key, the cell goes into EditMode and allows the user to override the value. If the key is not numeric, nothing happens...
That is working pretty well... the problem is that I find the code for it ugly...
I can't seem to find a neat way to handle all the numeric keys in a single condition, so I've made a switch case construct to deal with all the possible numeric keys, like this:
switch (e.KeyCode)
{
case Keys.D0:
case Keys.D1:
case Keys.D2:
case Keys.D3:
case Keys.D4:
case Keys.D5:
case Keys.D6:
case Keys.D7:
case Keys.D8:
case Keys.D9:
case Keys.Decimal:
case Keys.NumPad0:
case Keys.NumPad1:
case Keys.NumPad2:
case Keys.NumPad3:
case Keys.NumPad4:
case Keys.NumPad5:
case Keys.NumPad6:
case Keys.NumPad7:
case Keys.NumPad8:
case Keys.NumPad9:
[code to make the cell go to editMode, etc...]
Sure, it works, but there has to be a better and shorter way, right?
All I could find using Google is converting e.KeyCode to a char, but when using numeric keys, it goes gives letters even for the numeric values...
Thanks.

Try
if ((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) ||
(e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9) ||
e.KeyCode == Keys.Decimal)
{
// Edit mode
}

If you use the KeyPress event, the event signature has a KeyPressEventArgs with a KeyChar member that gives you the character for the numberpad keys. You can do a TryParse on that to figure out if its a number or not.
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
int i;
if (int.TryParse(e.KeyChar.ToString(), out i))
{
MessageBox.Show("Number");
}
}

Sorcerer86pt's solution was the simplest, however, when a user presses a control key, like backspace, then it breaks. To solve that problem, you can use the following snippet:
void KeyPress(object sender, KeyPressEventArgs e)
{
if(!Char.IsNumber(e.KeyChar) && !Char.IsControl(e.KeyChar))
{
//The char is not a number or a control key
//Handle the event so the key press is accepted
e.Handled = true;
//Get out of there - make it safe to add stuff after the if statement
return;
}
//e.Handled remains false so the keypress is not accepted
}
If you're using WPF, you might find that a TextBox doesn't have a KeyPressed event. To fix this, I used the following code.
void ValidateKeyPress(object sender, KeyEventArgs e)
{
char keyPressed = WPFUtils.Interop.Keyboard.GetCharFromKey(e.Key);
if (!Char.IsNumber(keyPressed) && !Char.IsControl(keyPressed))
{
//As above
e.Handled = true;
return;
}
}
You may notice the weird function call WPFUtils.Interop.Keyboard.GetCharFromKey(e.Key) this is one of the useful functions I've collected.
You can find it here.

Why use keycodes, when you can use this:
void Control_KeyPress(object sender, KeyPressEventArgs e)
{
if (Char.IsDigit(e.KeyChar))
{
//do something
}
else
{
//do something else
}
}
It's cleaner and even if microsoft decides to change all enums vlue, it still would work

On the msdn help page they use this code in their example:
// Determine whether the keystroke is a number from the top of the keyboard.
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
...
// Determine whether the keystroke is a number from the keypad.
if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)

A bit more condensed version:
private void KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !Char.IsDigit(e.KeyChar); // only allow a user to enter numbers
}

Just get the last char from the Key that will be number if a number was pressed.
This method works with KeyDown events not needing any other conditions.
Just call this static method and pass in the Key to check
public static bool IsNumber(Keys key)
{
string num = key.ToString().Substring(key.ToString().Length - 1);
Int64 i64;
if (Int64.TryParse(num, out i64))
{
return true;
}
return false;
}

void dataGridView1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
// Used this to find they key values.
//label1.Text += e.KeyValue;
// Check if key is numeric value.
if((e.KeyValue >= 48 && e.KeyValue <= 57) || (e.KeyValue >= 97 && e.KeyValue <= 105))
System.Console.WriteLine("Pressed key is numeric");
}

Related

Catch Alt + other key shortcut

I have to catch user's input to send a shortcut to my WPF application.I found on internet that I have to do something like this: Catch when a key is pressed:
void keyDown(object sender, KeyEventArgs e)
{
if (Keyboard.Modifiers.HasFlag(Modifiers.Shift))
KeyPressed.SetShift(true);
if (Key.Shift != e.Key && Key.LeftAlt != e.Key && ....)
KeyPressed.SetKey(e.Key);
}
where KeyPressed is a class with static boolean variables to catch if ⇧Shift, Alt or Ctrl and another key are pressed (with Alt and Ctrl instead of ⇧Shift in the if clause). The second if is to catch a key different from Alt, ⇧Shift, Control for the shortcut. For example, for the shortcut Alt+C we have:
KeyPressed.Shift = false;
KeyPressed.Alt = true;
KeyPressed.Ctrl = false;
KeyPressed.key = Key;
Where the last element is of type System.Window.Input.Key.Catch when a key is released:
void keyUp(object sender, KeyEventArgs e)
{
if (KeyPressed.getShift())
this.textField.Text += "+Shift";
if (KeyPressed.getKeyCode())
this.textField.Text += "+" + KeyPressed.k.toString();
KeyPressed.SetShift(false);
}
and here simply I append to a textField the input received, after that I set all keys to false to catch the next shortcut correctly. This code works fine for all shortcuts like Ctrl+A, Ctrl+Alt+C, ⇧Shift+L, Alt, but when I press the shortcut like Alt+V, it catchs only Alt, not the other key.
How can I manage this? Is there a way to handle shortcuts in a better manner?
You need to get the actual key when in case of a SystemKey (Alt etc), you can use this helper function to get the real key behind the system key.
public static Key RealKey(this KeyEventArgs e)
{
switch (e.Key)
{
case Key.System:
return e.SystemKey;
case Key.ImeProcessed:
return e.ImeProcessedKey;
case Key.DeadCharProcessed:
return e.DeadCharProcessedKey;
default:
return e.Key;
}
}
You could check my answer here for more info.
Store the Alt-modifier state in a local variable. I'm unsure of the reasons why but this made it work for me.
private bool _altModifierPressed = false;
private void Window_KeyDown(object sender, KeyEventArgs e)
{
_altModifierPressed = (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt));
if (_altModifierPressed && Keyboard.IsKeyDown(Key.V))
{
// code to handle Alt + V
}
}
UPDATE:
Alternatively, you could do something like this (no need for local variable)
if (((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) && Keyboard.IsKeyDown(Key.V))
{
// code to handle Alt + V
}
But I noticed that with either approach (since the enum has the Flag attribute) any combination of keys including Alt & V will work. So both execute if I for example press Alt+G+V. Good luck.
If you want to use [Alt + A] in KeyboardHook in Office VSTO, this is how it's used.
if (IsKeyDown(Keys.Menu) &&
keyData == Keys.A &&
KeyWasAlreadyPressed == false &&
!IsKeyDown(Keys.Controlkey) &&
!IsKeyDown(Keys.ShiftKey))
{
//Enter your code here
}
Note:
Key.Menu denotes Alt Keys
Also condition says, Alt+A (and do not invoke when control or shift key is pressed in addition to Alt + A)
switch (e.Key)
{
case Key.System:
if (((KeyboardEventArgs)e).KeyboardDevice.Modifiers == ModifierKeys.Alt)
{
if (e.SystemKey == Key.Left)
moiveVideoPsition(-30);
else if (e.SystemKey == Key.Right)
moiveVideoPsition(30);
}
break;
This work well for me

C# When using a KeyPress event on a text box, why cant i enter a minus sign?

Im using VS2010, and I have a text box... I assign a KeyPress on the box, abd set the method like so:
private void MyButton_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true;
}
I noticed that i am no longer able to enter any special keys such as the minus (-) and plus (+) sign into the textbox. Can someone please explain to me why i am no longer able to do this, and what i can do to fix this?
Ultimately I'm trying to only allow numeric keys to be entered, and i also want to allow the (-) minus sign, but if i cant get the minus sign in there, then i guess i wont be able to limit the text of the box
This should finish the job for you.
private void MyButton_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar >= '0' && e.KeyChar <= '9') return;
if (e.KeyChar == '+' || e.KeyChar == '-') return;
e.Handled = true;
}
Here is how it works. If the character typed is one that you want, simply return from the function and let the normal handler take care of it. All other characters are marked as handled and so processing on them stops. Since nothing is done with them they are essentially thrown away. You could put everything in one if statement but I left it this way for clarity
I changed your code a little and added logic that only accepts 1, 2 or +, which was one of your problem characters. Hope this helps you!
private void MyButton_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true;
if (e.KeyChar == '1' || e.KeyChar == '2' || e.KeyChar == '+') textBox1.AppendText(e.KeyChar.ToString());
}
Actually, you should do like so:
private void MyButton_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '1' || e.KeyChar == '2' || e.KeyChar == '+')
e.Handled = false;
else
e.Handled = true;
}
Of course, you'll want to replace the individual tests by a method that will return whether or not the key is allowed.
Cheers
As it is now, your code won't allow anything to be entered. The e.Handled statement cancels the key stroke. The code below will allow any numeric character, and the minus sign. If you only want the minus sign in the first position in the textbox you will have to test the TextLength property before allowing the character.
private void MyButton_KeyPress(object sender, KeyPressEventArgs e
{
int i = 0;
if (!int.TryParse(e.KeyChar.ToString(), out i))
{
if (e.KeyChar.CompareTo('-')!=0)
{
e.Handled = true;
}
}
}

Restrict numbers and letters in textbox - C#

I want to restrict what numbers and letters can be entered into a textbox. Let's say I only want to allow numbers 0-5 and letters a-d (both lower and uppercase).
I already tried using a masked text box but it only let me specify numbers only, letters only (both without restriction) or numbers and letters together but in a particular order.
Best scenario would be: user tries to enter number 6 and nothing gets entered into the textbox, same for letters outside the range a-f.
I think the best event to use would be the Keypress event, but I am at a loss as to how I can achieve the restriction thing.
Use the KeyPress Event for your textbox.
protected void myTextBox_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs)
{
e.Handled = !IsValidCharacter(e.KeyChar);
}
private bool IsValidCharacter(char c)
{
bool isValid = true;
// put your logic here to define which characters are valid
return isValid;
}
// Boolean flag used to determine when a character other than a number is entered.
private bool nonNumberEntered = false;
// Handle the KeyDown event to determine the type of character entered into the control.
private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
// Initialize the flag to false.
nonNumberEntered = false;
// Determine whether the keystroke is a number from the top of the keyboard.
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
{
// Determine whether the keystroke is a number from the keypad.
if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)
{
// Determine whether the keystroke is a backspace.
if(e.KeyCode != Keys.Back)
{
// A non-numerical keystroke was pressed.
// Set the flag to true and evaluate in KeyPress event.
nonNumberEntered = true;
}
}
}
//If shift key was pressed, it's not a number.
if (Control.ModifierKeys == Keys.Shift) {
nonNumberEntered = true;
}
}
// This event occurs after the KeyDown event and can be used to prevent
// characters from entering the control.
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
// Check for the flag being set in the KeyDown event.
if (nonNumberEntered == true)
{
// Stop the character from being entered into the control since it is non-numerical.
e.Handled = true;
}
}
Override the PreviewKeyDownEvent like this:
private void textBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.A || e.KeyCode == Keys.B || ...)
e.IsInputKey = true;
else
e.IsInputKey = false;
}
This will tell the textBox which keys it will consider as a user input or not.
Use the KeyDown event and if the e.Key is not in your allowable set, then just e.Handled = true.
An alternative would be accept all input, validate it and then provide useful feedback to the user, for example an error label asking them to enter data within a certain range. I prefer this method as the user knows something went wrong and can fix it. It is used throughout the web on web forms and would be not at all surprising for a user of your app. Pressing a key and getting no response at all might be confusing!
http://en.wikipedia.org/wiki/Principle_of_least_astonishment
The Keypress event is probably your best bet. Do a check there if the entered char is not the char you want, set e.SuppressKey to true to make sure the KeyPress event is not fired, and the char is not added to the textbox.
If you are using ASP.NET Web Forms a regular expression validation would be the easiest. In MVC, a jQuery library such as MaskedEdit would be a good place to start. The answers above document the Windows forms approach well.

C# Numeric Only TextBox Control [duplicate]

This question already has answers here:
numeric-only textbox as a control in Visual Studio toolbox
(4 answers)
Closed 9 years ago.
I am using C#.NET 3.5, and I have a problem in my project. In C# Windows Application, I want to make a textbox to accept only numbers. If user try to enter characters message should be appear like "please enter numbers only", and in another textbox it has to accept valid email id message should appear when it is invalid. It has to show invalid user id.
I suggest, you use the MaskedTextBox: http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.aspx
From C#3.5 I assume you're using WPF.
Just make a two-way data binding from an integer property to your text-box. WPF will show the validation error for you automatically.
For the email case, make a two-way data binding from a string property that does Regexp validation in the setter and throw an Exception upon validation error.
Look up Binding on MSDN.
use this code:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
const char Delete = (char)8;
e.Handled = !Char.IsDigit(e.KeyChar) && e.KeyChar != Delete;
}
You might want to try int.TryParse(string, out int) in the KeyPress(object, KeyPressEventArgs) event to check for numeric values. For the other problem you could use regular expressions instead.
I used the TryParse that #fjdumont mentioned but in the validating event instead.
private void Number_Validating(object sender, CancelEventArgs e) {
int val;
TextBox tb = sender as TextBox;
if (!int.TryParse(tb.Text, out val)) {
MessageBox.Show(tb.Tag + " must be numeric.");
tb.Undo();
e.Cancel = true;
}
}
I attached this to two different text boxes with in my form initializing code.
public Form1() {
InitializeComponent();
textBox1.Validating+=new CancelEventHandler(Number_Validating);
textBox2.Validating+=new CancelEventHandler(Number_Validating);
}
I also added the tb.Undo() to back out invalid changes.
this way is right with me:
private void textboxNumberic_KeyPress(object sender, KeyPressEventArgs e)
{
const char Delete = (char)8;
e.Handled = !Char.IsDigit(e.KeyChar) && e.KeyChar != Delete;
}
TRY THIS CODE
// Boolean flag used to determine when a character other than a number is entered.
private bool nonNumberEntered = false;
// Handle the KeyDown event to determine the type of character entered into the control.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
// Initialize the flag to false.
nonNumberEntered = false;
// Determine whether the keystroke is a number from the top of the keyboard.
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
{
// Determine whether the keystroke is a number from the keypad.
if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)
{
// Determine whether the keystroke is a backspace.
if (e.KeyCode != Keys.Back)
{
// A non-numerical keystroke was pressed.
// Set the flag to true and evaluate in KeyPress event.
nonNumberEntered = true;
}
}
}
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (nonNumberEntered == true)
{
MessageBox.Show("Please enter number only...");
e.Handled = true;
}
}
Source is http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress(v=VS.90).aspx
You can check the Ascii value by e.keychar on KeyPress event of TextBox.
By checking the AscII value you can check for number or character.
Similarly you can write logic to check the Email ID.
I think it will help you
<script type="text/javascript">
function isNumberKey(evt) {
var charCode = (evt.which) ? evt.which : event.keyCode
if (charCode > 32 && (charCode < 48 || charCode > 57) && (charCode != 45) && (charCode != 43) && (charCode != 40) && (charCode != 41))
return false;
return true;
}
try
{
int temp=Convert.ToInt32(TextBox1.Text);
}
catch(Exception h)
{
MessageBox.Show("Please provide number only");
}

Keydown event capturing number keys

VS 2008 SP1
I want to capture the number keys 0 to 9. And perform some action if those number are clicked.
I am using the code below. However, it doesn't seem to be working right. However, the code doesn't go into the switch as when I use the debugger to see what key value has been captured in the e.KeyValue it comes up with "LButton | ShiftKey | Space".
However, should it not display NumPad1?
Many thanks for the advice,
private void CATDialer_KeyDown(object sender, KeyEventArgs e)
{
// Play sound when use kits number key
switch (e.KeyValue)
{
case Keys.NumPad1:
// Do something here
break;
.
.
.
}
I'm using this Code
private void tb_mds_port_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 8) // do something if backspace is pressed
{
// ACTION
e.Handled = true;
}
}
For your code use something like this
if(e.KeyChar == (char)Keys.Return) // do something if return is pressed
{
//ACTION
e.Handled = true;
}

Categories

Resources