I have a windows forms app with a maskedtextbox control that I want to only accept alphabetic values in.
Ideally, this would behave such that pressing any other keys than alphabetic keys would either produce no result or immediately provide the user with feedback about the invalid character.
This question has probably been asked and answered a million times on every conceivable programming forum. Every answer provided has the distinction of being unique to the stated requirements.
Since you are using a MaskedTextBox, you have additional validation features available to you and do not really need to handle keypresses. You can simply set the Mask property to something like "L" (character required) or "?" (optional characters). In order to show feedback to the user that the input is not acceptable, you can use the BeepOnError property or add a Tooltip to show the error message. This feedback mechanism should be implemented in the MaskedInputRejected event handler.
The MaskedTextBox control offers a ValidatingType property to check input that passes the requirements of the Mask, but may not be the correct datatype. The TypeValidationCompleted event is raised after this type validation and you can handle it to determine results.
If you still need to handle keypress events, then read on...!
The method I would recommend in your case is that instead of handling the KeyDown event (you ostensibly do not need advanced key handling capability) or using a Regex to match input (frankly, overkill), I would simply use the built-in properties of the Char structure.
private void maskedTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
Char pressedKey = e.KeyChar;
if (Char.IsLetter(pressedKey) || Char.IsSeparator(pressedKey) || Char.IsPunctuation(pressedKey))
{
// Allow input.
e.Handled = false
}
else
// Stop the character from being entered into the control since not a letter, nor punctuation, nor a space.
e.Handled = true;
}
}
Note that this snippet allows you to handle punctutation and separator keys as well.
From MSDN (This code shows how to handle the KeyDown event to check for the character that is entered. In this example it is checking for only numerical input. You could modify it so that it would work for alphabetical input instead of numerical):
// 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;
}
}
This code will distinguish alphabetic character key presses from non alphabetic ones:
private void maskedTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (Regex.IsMatch(e.KeyChar.ToString(), #"\p{L}"))
{
// this is a letter
}
else
{
// this is NOT a letter
}
}
Update: note that the above regex pattern will match ONLY alphabetic characters, so it will not allow spaces, commas, dots and so on. In order to allow more kinds of characters, you will need to add those to the pattern:
// allow alphabetic characters, dots, commas, semicolon, colon
// and whitespace characters
if (Regex.IsMatch(e.KeyChar.ToString(), #"[\p{L}\.,;:\s]"))
// This is to allow only numbers.
// This Event Trigger, When key press event occures ,and it only allows the Number and Controls.,
private void txtEmpExp_KeyPress(object sender, KeyPressEventArgs e)
{
if(Char.IsControl(e.KeyChar)!=true&&Char.IsNumber(e.KeyChar)==false)
{
e.Handled = true;
}
}
//At key press event it will allows only the Characters and Controls.
private void txtEmpLocation_KeyPress(object sender, KeyPressEventArgs e)
{
if (Char.IsControl(e.KeyChar) != true && Char.IsNumber(e.KeyChar) == true)
{
e.Handled = true;
}
}
//Add a text box select it & goto Events & In the event list double click on "keypress" event.
if (!char.IsLetter(e.KeyChar))
{
MessageBox.Show("Enter only characters");
}
}
This works for me :)
private void txt_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !((e.KeyChar != 'ñ' && e.KeyChar != 'Ñ') && char.IsLetter(e.KeyChar));
}
Try this code
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !(char.IsLetter(e.KeyChar) || e.KeyChar == (char)Keys.Back || e.KeyChar == (char)Keys.Space);
}
Related
Good day. I'm having a hard time with this. TextBox1 should only accept numbers and if the user input a text, a message box will pop-up saying that only numbers can be entered.
I don't know how to do this since the message box should pop-up without clicking any button.
The user will just really enter numbers and if they enter non numerical value the message box will appear instantly.
Is this even possible?
I've tried the KeyPress events but I can still input letters. Please help.
This is a very standard implementation, with a minor twist of including a dialog box. In general a dialog box is just going to annoy the user and take the focus away from the form, it breaks the flow of the user interaction so we try to avoid it, however you can adapt the standard example listed in the MS Docs - KeyEventHandler Delegate documentation:
// 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;
}
}
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;
MessageBox.Show("Only numeric input is accepted");
}
}
Using the KeyEventArgs in this manner allows you access to the raw physical key that was pressed, and to separately prevent the textbox from accepting the key press.
This style of code is very useful when 3rd party controls (or your own code) has overriden the standard implementations. It is however possible to do it all in the KeyPress event handler:
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
// Check for the flag being set in the KeyDown event.
if (!Char.IsNumber(e.KeyChar) && e.KeyChar != '.')
{
// Stop the character from being entered into the control since it is non-numerical.
e.Handled = true;
MessageBox.Show("Only numeric input is accepted");
}
}
But that could still allow us to enter a value of "12.333...44..5" so a more complete example should extend one of the previous examples and compare against the current value in the textbox:
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
// Check for the flag being set in the KeyDown event.
bool isNumber = Char.IsNumber(e.KeyChar);
if (e.KeyChar == '.')
{
isNumber = !(sender as TextBox).Text.Contains(".");
}
if (!isNumber)
{
// Stop the character from being entered into the control since it is non-numerical.
e.Handled = true;
MessageBox.Show("Only numeric input is accepted");
}
}
This code in my form updates the textBox1.Text twice whenever number keys are pressed.
private void textBox1_KeyDown( object sender, KeyEventArgs e ) {
//MessageBox.Show();
if( char.IsNumber((char)e.KeyCode) ) {
textBox1.Text += (char)e.KeyCode;
}
}
Explain why if you can?
Modify the code or provide me a better solution for this.
Input ( in textbox1 ):
54321
Output:
1234554321
When you press a key, a character is already appended to your TextBox. Then you run the following code and, if the key represents a number, you append it again:
if (char.IsNumber((char)e.KeyCode)) {
textBox1.Text += (char)e.KeyCode;
}
If you want to suppress any key that's not a number, you could use this instead:
e.SuppressKeyPress = !char.IsNumber((char)e.KeyCode);
From the syntax I assume you are using WinForms for the following answer.
The key pressed event is not suppressed, so it still works like a normal key pressed event and adds the character to the text of the box. Additionally you add the character to the text yourself once again.
Try to suppress the key pressed event in case a key is pressed, you do not want to allow.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (!char.IsNumber((char)e.KeyCode))
{
e.SuppressKeyPress = true;
}
}
You can try like this:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = !(e.KeyValue >= 48 && e.KeyValue <= 57);
}
Check New keyboard APIs: KeyEventArgs.SuppressKeyPress
The problem is that "Handled" doesn't take care of pending WM_CHAR
messages already built up in the message queue - so setting Handled =
true does not prevent a KeyPress from occurring.
In order not to break anyone who has currently got e.Handled =
true, we needed to add a new property called SuppressKeyChar. If we
went the other way, if "handling" a keydown suddenly started to
actually work, we might break folks who accidentally had this set to
true.
Try this code to accept numbers only
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar))
e.Handled = true;
}
I have a TextBox control. After pressing space, I want, instead of whitespace, to put "|". This is my code:
void TextBox1KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Space)
{
textBox1.AppendText("|");
}
}
Problem is it doesn't write only "|", but "| ": After the pipe char, it puts a space and the cursor moves after that space. I tried to use this method:
textBox1.Text = textBox1.Text.Substring(0, (textBox1.TextLength - 1));
but it doesn't work because it deletes "|" instead of the space.
And another question is: I want to disable inserting " " when Space is pressed when textbox is empty. When u want to press space while textbox is empty, nothing happens, textbox will stay empty and cursor stay at the begining of textbox
i try this
void TextBox1KeyDown(object sender, KeyEventArgs e)
{
if (textBox1.Text.Length==0 && e.KeyCode == Keys.Space) {
textBox1.Text=string.Empty;
}
}
It doesnt work cause same reason like my previous question. That event is handled after " " is already added so textbox is not empty
PS: sorry for my english and thanks to whoever edit my post and fix my grammatical and spellig errors
Instead of KeyPress handle your requirement in the KeyDown event
void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Space && e.Modifiers == Keys.None)
{
e.SuppressKeyPress = true;
textBox1.AppendText("|");
}
}
As noted below from DrewMcGowen, this will add always the pipe at the end of the textbox text. If you move the cursor somewhere inside the current text the behavior of this approach is confusing and probably incorrect.
This code instead tries to place the pipe exactly where the cursor is
void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Space && e.Modifiers == Keys.None)
{
e.SuppressKeyPress = true;
int pos = textBox1.SelectionStart;
textBox1.Text = textBox1.Text.Substring(0, pos) + "|" + textBox1.Text.Substring(pos);
textBox1.SelectionStart = pos + 1;
}
}
Notice also that a check on the value of the Modifiers property of the KeyEventArgs parameter is mandatory. For example ALT+SPACE should activate the System Menu and not change your textbox in any way (see comment below from Mr HansPassant). Checking for Keys.None will avoid this logic also for CTRL and SHIFT modifiers, if you want these modifiers to be accounted for you need to change that check.
The OnKeyPress event is fired before the space is added.
The workflow is thus:
You press down [Space];
The event is fired adding | to the content; and
The space event itself is handled adding a space to the content.
You need to use KeyRelease or KeyUp...
Documentation says:
Use the KeyChar property to sample keystrokes at run time and to modify keystrokes under special run-time circumstances. For example, you can use KeyChar to disable non-numeric keypresses when the user enters a ZIP code, change all alphabetical keypresses to uppercase in a data entry field, or monitor the keyboard or other key input device for specific key combinations.
So all you need is
if (e.KeyChar == ' ')
{
e.KeyChar = '|';
}
You forgot e.Handled = true; to suppress the space.
Monkeying with the user input is rather unwise. It is very disorienting and plain just doesn't work in some cases. Obvious failure modes are the user typing Ctrl+V or using right-click + Paste to insert text. Do this correctly with the Validating event:
private void textBox1_Validating(object sender, CancelEventArgs e) {
textBox1.Text = textBox1.Text.Replace(' ', '|');
}
With high odds that you want to further improve this code by checking for two || next to each other or a leading or trailing |. You can set e.Cancel = true when you're unhappy, use ErrorProvider to give the user hints.
I have this code from MSDN that allows only numeric characters into a TextBox.
But I can't modify it to accept a "." as an input and limit to one.
Ex: 12.50 valid!
236.3247 valid!
2..5 invalid
//other non-numeric input invalid
Considering the code below:
private bool nonNumberEntered = false;
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
nonNumberEntered = false;
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
{
if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)
{
if (e.KeyCode != Keys.Back)
{
nonNumberEntered = true;
}
}
}
if (Control.ModifierKeys == Keys.Shift)
{
nonNumberEntered = true;
}
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (nonNumberEntered == true)
{
e.Handled = true;
}
}
Kindly post your modified code. Thanks a lot.
I would just validate the field as a Culture-sensitive number after they tab off or on a form submit. It's not really necessary or valuable to actually stop them from pressing . twice in the field. Often I find that kind of thing annoying, because I'm modifying what was there and I just haven't finished...
Use double.TryParse to test it properly.
I have a textbox that I only want digits and commas in, so it's similar to what you have.
I'd just run a regex on textbox.Text to match digits and zero or one decimal points with each key press. If the string that would be created doesn't match, then just disallow that character.
I think a .NET example is "^\d*.?\d*$"
From left to right:
^ at the beginning of the string
\d* zero or more digits
.? zero or one period
\d* zero or more digits
$ end of string
Not exactly what you have above but that would work.
I need to be able to lock down the valid characters in a textbox, I presently have a regex which I can check each character against such as
[A-Za-z]
would lock down to just Alpha characters.
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Back)
{
base.OnKeyPress(e);
return;
}
if (String.IsNullOrEmpty(this._ValidCharExpression))
{
base.OnKeyPress(e);
}
else
{
bool isValidChar = Regex.Match(e.KeyChar.ToString(),this._ValidCharExpression).Success;
if (isValidChar)
{
base.OnKeyPress(e);
}
else
{
e.Handled = true;
}
}
}
I had placed the regex code in the OnKeyPress code, but I wat to allow all special keys, such as Ctrl-V, Ctrl-C and Backspace to be allowed.
As you can see I have the backspace key being handled. However, Ctrl-V, for example cannot see the V key because it runs once for the ctrl key but does not see any modifiers keys.
What is the best way to handle this situation?
MaskedTextBox may be right for you.
You can also look at the FilterTextBox over at CodeProjct. You can use it (or the approach described) to do what you intend. The basic idea is to cancel the change before it is becoming visible (via an OnTextChanging event).
What if you put the validation in OnTextChanged instead of OnKeyPress, but each time it passes validation you save the value to a variable? Then you can revert if the user pastes or types an incorrect string, as well as give some other UI hint that something was invalid (e.g. set a Label's text).
Why don't you put the check for valid characters in the OnTextChanged event
and then deal with the Ctrl+C, Ctrl+V in the on key down
Also you can use the e.ModifierKeys == Keys.Control to test for control keys
http://msdn.microsoft.com/en-us/library/system.windows.forms.keypresseventargs.aspx
You can use one of the OnKeyPress / OnKeyUp / OkKeyDown events and then use the Char.IsLetter method to check that the entered key is a letter.
The solution that I have come up with is to check the keys in the OnKeyDown event and then setting a flag if the keypress should be handled, which is then check in the OnKeyPress event.
protected override void OnKeyDown(KeyEventArgs e)
{
Keys keyCode = (Keys)e.KeyValue;
base.OnKeyDown(e);
if ((e.Modifiers == Keys.Control) ||
(e.Modifiers == Keys.Control) ||
(keyCode == Keys.Back) ||
(keyCode == Keys.Delete))
{
this._handleKey = true;
}
else
{
// check if the key is valid and set the flag
this._handleKey = Regex.Match(key.ToString(), this._ValidCharExpression).Success;
}
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (this._handleKey)
{
base.OnKeyPress(e);
this._handleKey = false;
}
else
{
e.Handled = true;
}
}