I would like to know if there is a proper way for a textbox to accept only numbers.
For example, I want it to "stop" the user from filling it with "abcd1234" and only let him fill with "1234".
I tried following code and worked fine for me. The textbox will allow user to enter numbers only.
private void txtbox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
you can also try this
e.Handled = !(char.IsDigit(e.KeyChar));
You can evaluate the input using the following lines of code:
if (txtNumericBox.Text.All(char.IsDigit))
// Proceed
else
// Show error
If you define this as a string property with getter and setter then you can use like the following:
private string _MyNemericStringr;
public string MyNemericString
{
get { return _MyNemericStringr; }
set {
if (value.All(char.IsDigit))
_MyNemericStringr = value;
else
_MyNemericStringr = "0";
}
}
In the second example, if you assign any non-digit value to the property then it will return the value as "0". otherwise it will process as usual.
you can try this simple code.
private void keypressbarcode(object sender, KeyPressEventArgs e)
{
e.Handled = !(char.IsDigit(e.KeyChar) || e.KeyChar == (char)Keys.Back);
}
it only accept numeric values and Backspace
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;
}
}
private void inputBox_KeyPress(object sender, KeyPressEventArgs e)
{
stringScan();
var regex1 = new Regex(#"[^+^\-^\b^\r\n]");
var regex2 = new Regex(#"[^0-9^+^\-^/^*^#^\b^\r\n]");
if (ListBox.Items.Count == 0 && string.IsNullOrWhiteSpace(inputBox.Text))
{
if (regex1.IsMatch(e.KeyChar.ToString()))
{
e.Handled = true;
toolTip1.Show("Plus or minus first then followed by numbers.", inputBox, 1500);
}
}
else
{
if (regex2.IsMatch(e.KeyChar.ToString()))
{
e.Handled = true;
}
}
}
public void stringScan()
{
char last_char = inputBox.ToString()[inputBox.ToString().Length - 1];
Console.WriteLine(last_char);
}
How can i get the last letter/number of a string?. Its really hard to explain so I'll show some screenshots.
the output should show "0" not "1".
It always show the "previews last" and not the latest one that i typed in the textbox.
Remember, when the event inputBox_KeyPress is raised, the typed key isn't added yet. Also, don't use regex for this. It will be overcomplicated.
Try the TextChanged event.
Text box key change will be executed every time u change the content of the text box
So for every value u enter u will be calling the string scan
This can be limited if u know what length the text is going to be
What about you try this:
public void stringScan()
{
String last_char = inputBox.ToString();
Console.WriteLine(last_char[last_char.Length-1]);
}
If you want last typed char I suggest:
private void inputBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
Console.WriteLine(e.Text);
}
If you want last char in textbox I suggest TextChanged event as already told by Jeroen van Langen:
private void inputBox_TextChanged(object sender, TextChangedEventArgs e)
{
string inputString = ((TextBox)sender).Text;
char lastChar = inputString.Last();
Console.WriteLine(lastChar);
}
Hope code samples help you
Edit:
Now I get that you probably want to get integer from textbox, if that's the matter, Get integer from Textbox could help you, code sample:
private void inputBox_TextChanged(object sender, TextChangedEventArgs e)
{
string inputString = ((TextBox)sender).Text;
int valueFromTextBox;
if (int.TryParse(inputString, out valueFromTextBox))
{
//parsing successful
}
else
{
//parsing failed.
}
}
How to construct a Regex to allow enter CA or CH?
Tried \bC(A|H) and C(A|H) but I need to validate it in the KeyPress event of the textbox like this;
private Regex _regex = new Regex(#"C(A|H)");
private void txtCaCh_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsControl(e.KeyChar))
return;
if (!_rolfRegex.IsMatch(e.KeyChar.ToString().ToUpper()))
e.Handled = true;
}
You can use
if (e.KeyChar != (char)8) // Not a backspace key
if (!Regex.IsMatch(txtCaCh.Text.ToUpper() + e.KeyChar.ToString().ToUpper(), #"^C[AH]?$")) // If the value is not CH or CA
e.Handled = true; // Do not let it pass
Inside the KeyPress event handler, txtCaCh.Text contains the value before adding the next key. So, to get the full value we need to add the newly pressed key value. After that, we can check if the value is the one we can accept.
^C[AH]?$
This regex accepts C or CA or CH values, so that we can type them in.
Then, you need to validate it at some other event with ^C[AH]$ (Leave event, for example).
Live validation cannot be performed at the same time as final validation.
instead of validating the e.KeyChar, validate the content of the control itself:
if(!_rolfRegex.IsMatch((sender as TextBox)?.Value.ToUpper())
e.Handled = true;
Your pattern must be ^C[AH]$. Start of input (^), folowing C, then A or H ([AH])and end of input ($).
private Regex _regex = new Regex(#"^C[AH]$");
private void txtCaCh_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsControl(e.KeyChar))
return;
var txtBox = (TextBox)sender;
if (txtBox.Text != null && _rolfRegex.IsMatch(txtBox.Text.ToUpper()))
{
// TODO now we have match, handle it
}
}
I have several text boxes and would like to format them all the same way with these rules:
// limits to number, control keys, and decimal
// goes to the next text box when enter
private void tb_text1_KeyPress_1(object sender, KeyPressEventArgs e)
{
string newString = Regex.Replace(tb_text1.Text, "[^.0-9]", "");
tb_text1.MaxLength = 6;
e.Handled = (!char.IsDigit(e.KeyChar) && !Char.IsControl(e.KeyChar) && e.KeyChar != '.');
if (e.KeyChar == (char)(Keys.Enter))
{
this.GetNextControl(ActiveControl, true).Focus();
}
}
// removes restricted chars
private void tb_text1_Enter(object sender, EventArgs e)
{
tb_text1.Text = Regex.Replace(tb_text1.Text, "[^.0-9]", "");
}
// applies format at exit
private void tb_text1_Leave(object sender, EventArgs e)
{
tb_text1.Text = string.Format("{0,-6} [Ohm]", decimal.Parse(tb_text1.Text));
}
What is the best way? create a new text box class based on the text box?
Thanks.
Replace in methods your "tb_text1" variable to the "((TextBox)sender)", and now You can use Your code for any textbox.
It is very easy to do it with javascript . Please try that. I have done it i'm not able to find piece of that code right now . It is worth the effort because it will be very fast and will be running on client side.
I have one TextBox with binding on DateTime type. I need to get a dot after first 2 chars and second 2 chars, for example: 12.12.1990.
I'm using behavior in TextChanged event, that code:
void tb_TextChanged(object sender, TextChangedEventArgs e)
{
int i = tb.SelectionStart;
if (i == 2 || i == 5)
{
tb.Text += ".";
tb.SelectionStart = i + 1;
}
}
That is working, but if I want to delete text by backspace, obviously I can't delete dots, because event is called again.
What is better way to solve it?
Solved
It works
But if you can, you may fix my algorithm.
public string oldText = "";
public string currText = "";
private void TextBox1_TextChanged(object sender, TextChangedEventArgs e)
{
oldText = currText;
currText = TextBox1.Text;
if (oldText.Length > currText.Length)
{
oldText = currText;
return;
}
if (TextBox1.Text.Length == currText.Length)
{
if (TextBox1.SelectionStart == 2 || TextBox1.SelectionStart == 5)
{
TextBox1.Text += ".";
TextBox1.SelectionStart = TextBox1.Text.Length;
}
}
}
I would do it in the KeyPress event, so you can filter by what kind of key it was (using the KeyChar argument with Char.IsLetter() and similar functions).
Also, add the dot when the next key is pressed. If the user has typed "12", don't add a dot yet. When the user presses 1 to add the second "12", add it then (before the new character).
Use String Format in the xaml control like so
StringFormat='{}{0:dd.MM.yyyy}'
I just tested it and this will even convert slashes to the dots.
For example
<TextBox.Text>
<Binding Path="Person.DateOfBirth" UpdateSourceTrigger="LostFocus" StringFormat='{}{0:dd.MM.yyyy}'></Binding>
</TextBox.Text>
If you are using a datepicker then you will need to override its textbox template as in the link below with the String Format above.
This link may help if if you are trying to apply it to a datepicker.
I recommend you to use a DateTimePicker and change its Format property to Short. Another option is to change your TextBox to a MaskedTextBox and changing its Mask property to ShortDate (00/00/0000) .DateTimePicker allows you not to do much about validating datetime values. But if you use a MaskedTextBox you should validate it. Sample link shows how to do validation.
I have modified above code
private void txt_in1_TextChanged(object sender, TextChangedEventArgs e)
{
int i = txt_in1.SelectionStart;
if (bsp1 != 1)
{
if (i == 2)
{
txt_in1.Text += ":";
txt_in1.SelectionStart = i + 1;
}
}
}
private void txt_in1_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Back)
{
bsp1 = 1;
}
else
{
bsp1 = 0;
}
}
I have taken another event which is keyup (equivalent keypress event), In that whenever backspace is detected it will flag bsp1 variable, which intern stop the text change event to put ":". here "bsp1" is define as global variable. (Code is for wpf, c#).