I'm building a form in a C# WinRT app, and I'd like to restrict the characters in one of the TextBox components to numerals only. (This TextBox would be for a user to enter a year into.)
I've searched for a while, but haven't been able to figure this one out without setting up an event listener on the TextChanged event, and inspecting the text property on every key press. Is there a way to simply say that a user can only enter specific characters into a TextBox?
The simplest thing that could possibly work is to bind to the OnTextChanged event and modify the text according to your rules.
<TextBox x:Name="TheText" TextChanged="OnTextChanged" MaxLength="4"/>
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
if (TheText.Text.Length == 0) return;
var text = TheText.Text;
int result;
var isValid = int.TryParse(text, out result);
if (isValid) return;
TheText.Text = text.Remove(text.Length - 1);
TheText.SelectionStart = text.Length;
}
However, I'd shy away from this approach since the mantra of Metro is touch first UI and you can easy do it in a touch first manner with a FlipView control.
Try setting TextBox.InputScope property to InputScopeNameValue.Number, as mentioned in Guidelines and checklist for text input in MSDN.
Valid Year
DateTime newDate;
var validYear = DateTime.TryParseExact("2012", "yyyy", CultureInfo.InvariantCulture,
DateTimeStyles.None, out newDate); //valid
Invalid Year
var validYear = DateTime.TryParseExact("0000", "yyyy", CultureInfo.InvariantCulture,
DateTimeStyles.None, out newDate); //invalid
This seems to work for me:
private void TextBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
if ((e.Key < VirtualKey.Number0) || (e.Key > VirtualKey.Number9))
{
// If it's not a numeric character, prevent the TextBox from handling the keystroke
e.Handled = true;
}
}
See the documentation for the VirtualKey enumeration for all the values.
Based on a posting at link, adding the tab to allow navigation.
private void decimalTextBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
bool isGoodData; // flag to make the flow clearer.
TextBox theTextBox = (TextBox)sender; // the sender is a textbox
if (e.Key>= Windows.System.VirtualKey.Number0 && e.Key <= Windows.System.VirtualKey.Number9) // allow digits
isGoodData = true;
else if (e.Key == Windows.System.VirtualKey.Tab)
isGoodData = true;
else if (e.Key >= Windows.System.VirtualKey.NumberPad0 && e.Key <= Windows.System.VirtualKey.NumberPad9) // allow digits
isGoodData = true;
else if (e.Key == Windows.System.VirtualKey.Decimal || (int)e.Key == 190) // character is a decimal point, 190 is the keyboard period code
// which is not in the VirtualKey enumeration
{
if (theTextBox.Text.Contains(".")) // search for a current point
isGoodData = false; // only 1 decimal point allowed
else
isGoodData = true; // this is the only one.
}
else if (e.Key == Windows.System.VirtualKey.Back) // allow backspace
isGoodData = true;
else
isGoodData = false; // everything else is bad
if (!isGoodData) // mark bad data as handled
e.Handled = true;
}
Use a MaskedTextBox control. For numerals only, just use the Mask property to specify the characters and the length, if any. e.g. if you want only five numbers to be entered, you set the mask property to "00000". Simple as that. Windows handles the restriction for you.
Related
I have a project in C#.net using a WPF textbox that validates a character like * as the first character entered. If this character is entered, the rest of the text is good but I cannot show nor use the character. How can I remove the character from the string early enough to not show it? I've attempted using the KeyDown event but while the event is active, there is no data to remove. And if I use the KeyUp event the data is shown for a second. I've previously used a KeyPress event in VB6 to achieve this which worked because the value was simultaneously in the code but not in the textbox. As far as I can tell a WPF textbox does not have this event. What can I do?
Code:
private void UserInput_KeyUp(object sender, KeyEventArgs e)
{
//get ascii value from keyboard input
int Ascii = (int)e.Key;
//get char value to know what to remove as a string
char CharAscii = (char)Ascii;
If(Ascii == InputPrefix)
{
PrefixValidated = true;
UserInput.Text = UserInput.Text.Replace(CharAscii.ToString(), string.Empty);
}
}
The same code is in the KeyDown event and I've tried it using one or the other and both.
it may be a bit of a rough solution but you could use a PreviewTextInupt event I belive.
private bool PrefixValidated = false;
private string CheckUserInput;
private void TextBox1_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
CheckUserInput = CheckUserInput + e.Text;
if (CheckUserInput.ElementAt(0).ToString() == "*" && e.Text != "*")
{
e.Handled = false;
}
else if (CheckUserInput.ElementAt(0).ToString() == "*")
{
PrefixValidated = true;
e.Handled = true;
}
else
{
e.Handled = true;
}
}
Thanks to Dark Templar for helping with the discovery of this solution. Using PreviewTextInput and validating the character only if there are no other characters in the textbox seems to give the correct result.
Setting e.Handled = true stops the character from actually entering the textbox even for a second so the user is never aware of the prefix.
Code:
private void UserInput_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
//if this is the first character entered, the textbox is not yet populated
//only perform validation if the character is a prefix
if (UserInput.Text != "")
return;
char CharAscii = (char)ScannerPrefix;
if (e.Text == CharAscii.ToString())
{
PrefixValidated = true;
e.Handled = true;
}
}
I have a textbox that accepts only numbers, no other characters. And I created the following function in the keypress method for that:
private void txtRGIE_KeyPress(object sender, KeyPressEventArgs e)
{
if (!Char.IsDigit(e.KeyChar) && e.KeyChar != (char)8)
{
e.Handled = true;
}
}
Validation is working when I type, I can't type special characters or letters like I wanted. However, if I copy a numeric string that contains dots or other characters and paste it into the field, it accepts normally. For example, if you copy: 323.323 / 323 and paste into the field, it will accept. How do I validate the characters I paste, allowing only numbers?
I have a textbox that accepts only numbers
And that's the flaw; saying "I have a knife here that i'm trying to use as a screwdriver, but i keep cutting myself with it, so i filed it smooth, but it's too big to get into the screw hole, so I filed it small, but it doesn't turn a + shaped screw very well, and the tip isn't hardened so it keeps breaking.."
The answer is to use a + shaped screwdriver, rather than keep repeatedly trying to kludge something not made for the job, into something that will do the job
A NumericUpDown control is the right tool for this job; it accepts only numbers, has configurable decimal places, and upper and lower limits, cannot have alphameric text typed or pasted into it and, bonus, the user can use the Up and Down cursor keys to change the value
NUD is a drop in replacement for your textbox, it's free and it's part of the standard lib so there isn't anything to install - just remember to get the .Value, not the .Text, and that it's a decimal, so you might want to cast it to something else to use it (double? int?) depending on what your app expects
If you don't like the little up down buttons, see here
you can use :
private void txtRGIE_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) &&
(e.KeyChar != '.'))
{
e.Handled = true;
}
// only allow one decimal point
if ((e.KeyChar == '.') && ((sender as TextBox).Text.IndexOf('.') > -1))
{
e.Handled = true;
}
}
or you can use a NumericUpDown instead
refer to this answers so you understand more.
You could use a MaskedTextBox instead of a regular one.
As already mentioned a NumericUpDown control is a good choice and to make it appear like a TextBox you can hide the up/down arrows e.g.
amountNumericUpDown1.Controls[0].Hide();
Or create a custom version with no up/down arrows and in this case no beep when pressing enter key.
public class SpecialNumericUpDown : NumericUpDown
{
public SpecialNumericUpDown()
{
Controls[0].Hide();
TextAlign = HorizontalAlignment.Right;
}
protected override void OnTextBoxResize(object source, EventArgs e)
{
Controls[1].Width = Width - 4;
}
public delegate void TriggerDelegate();
public event TriggerDelegate TriggerEvent;
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == (Keys.Return))
{
e.Handled = true;
e.SuppressKeyPress = true;
TriggerEvent?.Invoke();
return;
}
base.OnKeyDown(e);
}
}
Windows Forms C# - I would like to make a textbox that automatically changes each time a user types or deletes one key from the textbox. I developed part of code.
//This will convert value from textbox to currency format when focus leave textbox
private void txtValormetrocubico_Leave(object sender, EventArgs e)
{
decimal cubic = Convert.ToDecimal(txtValormetrocubico.Text);
txtValormetrocubico.Text = string.Format("{0:c}", Convert.ToDecimal(cubic));
MessageBox.Show(txtValormetrocubico.Text);
}
//this only allow numbers and "." and "," on textimbox imput
private void txtValormetrocubico_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar)
&& !char.IsDigit(e.KeyChar)
&& e.KeyChar != '.' && e.KeyChar != ',')
{
e.Handled = true;
}
// only allow one decimal point
if (e.KeyChar == '.'
&& (sender as TextBox).Text.IndexOf('.') > -1)
{
e.Handled = true;
}
if (e.KeyChar == ','
&& (sender as TextBox).Text.IndexOf(',') > -1)
{
e.Handled = true;
}
}
The first time I enter a value in the text box, the value is converted to currency format perfectly, like 300 to $ 300.00. But I edit this textbox value again and press enter, it gives an error: "Input String was not in a Correct Format" pointing to the line below:
decimal cubic = Convert.ToDecimal(txtValormetrocubico.Text);
I think the problem is caused by the fact that the value is already in decimal format. So when I click on the field and press enter again, it causes an error because the value cannot be parsed. How do I avoid this error ?
EDIT:
My previous question was my first. As I am new user and don't have much knowledge in C#, I forgot to post my code. After studying some more, I made part of it work. Only this little problem remains. Please vote up, I was banned and cant make new questions because I had 7 down votes.
Thanks guys.
The problem is that the string contains the currency symbol
private void TextBox_LeaveEvent(object sender, EventArgs e)
{
var tb = sender as TextBox;
if(tb.Text.Length>0){
decimal cubic = Convert.ToDecimal(tb.Text);
tb.Text = string.Format("{0:c}", Convert.ToDecimal(cubic));
label1.Text = tb.Text;
}
}
Above the textbox.Text is set to contain the currency information:
tb.Text = string.Format("{0:c}", Convert.ToDecimal(cubic));
Since the textbox now contains a currency symbol (like € or $) the Convert.ToDecimal fails as soon as the TextBox_LeaveEvent fires again:
decimal cubic = Convert.ToDecimal(tb.Text);
If you bing for c# masked textbox you can find articles about masked textboxes. You cold also test if the string contains any non-number-charakters (if(tbText.IndexOf(" ") >-1){...})
Update with basic example
I uploaded a very basic example to remove the currency formating to github:
string RemoveCurrencyFormating(string input)
{
if(input.IndexOf(" ") !=-1){
var money = input.Substring(0, input.IndexOf(" ")-1);
return String.Format("{0:D0}", money);
}
return ""; // Todo: add Error Handling
}
On TextBox Enter Event you can do the following:
void TextBox_EnterEvent(object sender, EventArgs e)
{
var tb = sender as TextBox;
tb.Text = RemoveCurrencyFormating(tb.Text);
}
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.
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");
}