Locking down valid characters in a Textbox - c#

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;
}
}

Related

TextBox input validation, numbers only

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");
}
}

C# Textbox Keypress Control Help

I have a standard textbox that I want to perform an action on a keypress. I have this code currently:
private void idTextEdit_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter/Return)
{
e.Handled = true;
SearchButtonClick(sender, EventArgs.Empty);
}
}
The problem is, I have tried both Enter and Return up there which is the reason for that. It is only firing that check for normal keys that are not like shift, control, etc. How can I design this so that it will pick up and use the enter/return key in the same way?
You should use the KeyDown event instead:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return)
{
//...
}
}
If it for some reason has to be KeyPress, you can use (char)13 or '\r' for your check, though I doubt that would work well on a non-Windows OS.
if (e.KeyChar == '\r')
You cannot just cast Keys.Return to a char, because it's a bitflag enum and doesn't just hold the corresponding ASCII code.
Use the KeyDown event instead.

c# how to capture Ctrl-R from a textbox

I have a from that has a text box and I'm trying to determine if Ctrl-R is pressed within this text box. I can detect the keys separately using:
private void CheckKeys(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if(e.KeyChar == (char)Keys.R)
{
// ...
}
if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
{
// ...
}
}
How do I determine if they pressed at the same time?
If possible, change your event to KeyDown/KeyUp, everything will be easier. (Note that this solution is not always applicable)
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == (Keys.Control | Keys.R))
{
}
}
See Mitch's answer on how to construct the bit flag logic correctly, as long as he undeletes it. Here's something that will work, if he doesn't decide to. You basically need to check if both conditions are true at the same time:
bool isRKeyPressed = e.KeyChar == (char)Keys.R;
bool isControlKeyPressed = (Control.ModifierKeys & Keys.Control) == Keys.Control;
if (isRKeyPressed && isControlKeyPressed)
{
// Both ...
}
else if (isRKeyPressed)
{
// R key only ...
}
else if (isControlKeyPressed)
{
// CTRL key only ...
}
else
{
// None of these...
}
Throw away any of these checks that you don't care about.
Also, you might want out check out this alternative approach:
http://www.codeguru.com/columns/experts/article.php/c4639
They override the ProcessCmdKey method on their form (possibly on individual controls?):
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.processcmdkey.aspx

How to make Textbox only accept alphabetic characters

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);
}

How to make Enter on a TextBox act as TAB button

I've several textboxes. I would like to make the Enter button act as Tab. So that when I will be in one textbox, pressing Enter will move me to the next one. Could you please tell me how to implement this approach without adding any code inside textbox class (no override and so on if possible)?
Here is the code that I usually use.
It must be on KeyDown event.
if (e.KeyData == Keys.Enter)
{
e.SuppressKeyPress = true;
SelectNextControl(ActiveControl, true, true, true, true);
}
UPDATE
Other way is sending "TAB" key! And overriding the method make it so easier :)
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Enter))
{
SendKeys.Send("{TAB}");
}
return base.ProcessCmdKey(ref msg, keyData);
}
You can write on the keyDown of any control:
if (e.KeyCode == Keys.Enter)
{
if (this.GetNextControl(ActiveControl, true) != null)
{
e.Handled = true;
this.GetNextControl(ActiveControl, true).Focus();
}
}
GetNextControl doesn't work on Vista.
To make it work with Vista you will need to use the code below to replace the this.GetNextControl...:
System.Windows.Forms.SendKeys.Send("{TAB}");
You don't need to make an "enter event handler"
All you need to do is make a "central" KeyDown event:
example
private void General_KeyDown(object sender, KeyPressEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
if (this.GetNextControl(ActiveControl, true) != null)
{
e.Handled = true;
this.GetNextControl(ActiveControl, true).Focus();
}
}
}
Then all you have to do is go to designer select all textboxes you wish to cycle through with EnterKey (select them by holding down Ctrl and clicking on textbox with the mouse) then go to Events(thunder like button), search Keydown event and type inside General_KeyDown. Now all your selected Textboxes will have the same keydown event :) This makes everything muuuuch much easier, cause imagine a form with 100 textboxes and you want to cycle through all with enter.... making an apart event for each texbox is... well not a proper way to make a program, it ain't neat. Hope it helped!!
Blockquote
This worked for me
if (e.Key == Key.Enter)
((TextBox)sender).MoveFocus(new TraversalRequest(new FocusNavigationDirection()));
It is important to note that if you will get an annoying "ding" or warning sound each time that the control is expecting an associated button control and e.Handled = true isn't always the answer to rid yourself of the noise/sound/ding.
If the control (i.e. single-line textbox) is expecting an associated button to 'ENTER' your entry, then you must also deal with the 'missing' control.
e.Handled = e.SuppressKeyPress = true;
This may be helpful when getting rid of the 'ding' sound.
For what it's worth- in my circumstance my users needed to use the "ENTER KEY" as we were transitioning from a terminal/green-screen application to a windows app and they were more used to "ENTER-ing" through fields rather than tabbing.
All these methods worked but still kept the annoying sound until I added e.SuppressKeyPress.
If you define Tab Order of all controls and make Form.KeyPreview = True, only need this:
Private Sub frmStart_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Enter Then
System.Windows.Forms.SendKeys.Send("{TAB}")
End If
End Sub
I use this code in one of the text box keydown event
if (e.KeyData == Keys.Enter)
{
e.SuppressKeyPress = true;
SelectNextControl(ActiveControl, true, true, true, true);
}
Unable handle this keydown event for all text boxes in my form. Suggest something. Thanks
I don't do it at the form level. I create a single method that I share across all my inputs KeyDown event that I want to do this with (with one exception):
private void alltextBoxes_KeyDown(object sender, KeyEventArgs e)
{
try
{
if (e.KeyCode == Keys.Enter)
{
e.SuppressKeyPress = true;
SelectNextControl(ActiveControl, true, true, true, true);
}
}
catch
{
}
}
If I'm writing a control that I want to use in other applications, I give the last input its own method like this:
private void lastinput_KeyDown(object sender, KeyEventArgs e)
{
try
{
if (e.KeyCode == Keys.Enter)
{
e.SuppressKeyPress = true;
System.Windows.Forms.SendKeys.Send("{TAB}");
}
}
catch
{
}
}
Otherwise, the control just loops inside itself when you try to run it in another project. You could use the second way everywhere but I think the 1st is the preferred way.
For those of you that code in vb...
Public Class NoReturnTextBox
Inherits System.Windows.Forms.TextBox
Const CARRIAGE_RETURN As Char = Chr(13)
' Trap for return key....
Private Sub NoReturnTextBox_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
If e.KeyChar = CARRIAGE_RETURN Then
e.Handled = True
System.Windows.Forms.SendKeys.Send(vbTab)
End If
End Sub
End Class
This is the solution I use for VB.NET
Set Keypreview=True in your form properties.
Put this code in form keydown event:
If (e.KeyData = Keys.Enter) Then
'for any multiline control, you have to exit to let multiline 'textbox intro 'keypressing makes line skips.
If ActiveControl.Name = txtMyMutilineTextBox.Name Then Exit Sub
e.SuppressKeyPress = True
SelectNextControl(ActiveControl, True, True, True, True)
End If
Enjoy !!!!
Xabier Aberasturi Larruzea
This is better because when enter u can do focus the next tab.. U need setting TAB Order first
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Enter))
{
SelectNextControl(ActiveControl, true, true, true, true);
}
return base.ProcessCmdKey(ref msg, keyData);
}
Taking a wild guess:
// on enter event handler
parentForm.GetNextControl().Focus();
I would combine what Pharabus and arul answered like this:
private void textBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == ‘\r’)
{
e.Handled = true;
parentForm.GetNextControl().Focus()
}
}
Let me know if this helps! JFV

Categories