I'm trying to see if the user has pressed a decimal separator in a text box, and either allow or suppress it depending on other parameters.
The NumberdecimalSeparator returns as 46, or '.' on my US system. Many other countries use ',' as the separator. The KeyDown event sets the KeyValue to 190 when I press the period.
Do I just continue to look for commas/periods, or is there a better way?
The call
CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator
gets the decimal separator for the current user interface culture. You can use other cultures to get the separator for other languages.
EDIT
From the 166 cultures that are reported in my system (CultureInfo.GetCultures(CultureTypes.SpecificCultures).Count()), it seems that only two separators are used: period and comma. You can try this in your system:
var seps = CultureInfo.GetCultures(CultureTypes.SpecificCultures)
.Select(ci => ci.NumberFormat.NumberDecimalSeparator)
.Distinct()
.ToList();
Assuming that this is true, this method may be helpful (note that the keyCode is OR'ed with the modifiers flag in order to eliminate invalid combinations):
private bool IsDecimalSeparator(Keys keyCode, Keys modifiers)
{
Keys fullKeyCode = keyCode | modifiers;
if (fullKeyCode.Equals(Keys.Decimal)) // value=110
return true;
string uiSep = CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator;
if (uiSep.Equals("."))
return fullKeyCode.Equals(Keys.OemPeriod); // value=190
else if (uiSep.Equals(","))
return fullKeyCode.Equals(Keys.Oemcomma); // value=188
throw new ApplicationException(string.Format("Unknown separator found {0}", uiSep));
}
A last note: According to Keys enumeration, the value 46 that you mention corresponds to the DEL (Delete) key (i.e. the point when Num Lock is OFF).
The problem here is that the values in the KeyEventArgs are key codes, not characters. If you handle KeyPress instead, you will get a char in the KeyPressEventArgs which you can use for the comparison.
Note: You should really compare the NumberDecimalSeparator characters as it is a string, not a single character so you need to consider scenarios where there is more than one character in the string.
If you need know if the char pressed is decimal separator:
private void Control_KeyPress(object sender, KeyPressEventArgs e)
{
char separator = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
if (e.KeyCahr == separador)
{
// true
}
else
{
// false
}
}
But, if you need acept decimal numpad key as decimal separator of any culture:
private bool decimalSeparator = false;
private void Control_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Decimal)
decimalSeparator = true;
}
private void Control_KeyPress(object sender, KeyPressEventArgs e)
{
if (decimalSeparator)
{
e.KeyChar = System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0];
decimalSeparator = false;
}
}
Related
I need real numbers in TextBox. I try my code online here
"^-{0,1}[0-9]{1,3},{0,1}[0-9]{1,2}$"
and its working perfectly, but in my project not working.
Please show me how I must do it
Would TryParse works for you? From MSDN:
Converts the string representation of a number in a specified style and culture-specific format to its double-precision floating-point number equivalent. A return value indicates whether the conversion succeeded or failed.
And for you, it could be something like this:
private void c_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
double num;
e.Handled = double.TryParse(e.Text, out num);
// if e.Text is a number, e.Handled will be true and num = e.Text
}
private void TextBox_TextChanged(object sender, EventArgs e)
{
string value = TextBox.Text.Replace(",", "");
double dbl;
if (double.TryParse(value, out dbl))
{
TextBox.TextChanged -= TextBoxTextChanged;
TextBox.Text = string.Format("{0:#,#0}", dbl);
TextBox.SelectionStart = TextBox.Text.Length;
TextBox.TextChanged += TextBoxTextChanged;
}
}
I used above code for making Calculator. I want to get results comma with decimal value. I want to type 1,234.1234 in the
textBox, but I can not type 1,234.1234 in the Text Box. I mean comma with decimal value not getting.
Can anybody kindly please help me to solve this problem ?
You have to provide a Culture that uses . as thousands sign.
Normally you want to use the users current culture.
double.TryParse(value, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.CurrentCulture, out dbl)
Try this:
int value = 300000
String.Format("{0:#,###0}", value);
// will return 300,000
http://msdn.microsoft.com/en-us/library/system.string.format.aspx
I have a TextBox where I want to let users enter hexadecimal values (excluding the 0x prefix) in a comma separated list. The problem is that I only want each value to be a length of four characters. Following this answer, I use the KeyPress event handler to do this check that the user can only enter a digit:
private void filterIDTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!Char.IsControl(e.KeyChar) && !Char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
}
With Regex, we can restrict the user even more to only allow 0-9, A-F, a-f, and comma like this:
private void filterIDTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!Char.IsControl(e.KeyChar) && !Regex.IsMatch(e.KeyChar.ToString(), "[0-9A-Fa-f,]"))
{
e.Handled = true;
}
}
Is there any way I can use regex to make sure there are no more than 4 characters in between each comma? I tried using "[0-9A-Fa-f,]{0:4}" but this didn't work because I am doing the match only on the char, not the TextBox's text.
With that, I'm sure I'll have to use something other than KeyPress, but I still have been unsuccessful in writing the Regex statement for only allowing values up to 4 characters.
First you need to validate the entire text for this to work so validate filterIDTextBox.Text plus the key that was pressed. Second you need a regular expression that validates the entire field.
private void filterIDTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
string newValueIfAllowed = filterIDTextBox.Text + e.KeyChar.ToString();
if (!Char.IsControl(e.KeyChar)
&& (!Regex.IsMatch(e.KeyChar.ToString(), "[0-9A-Fa-f,]")
|| !Regex.IsMatch(newValueIfAllowed , "^([0-9A-Fa-f]{1,4},)*[0-9A-Fa-f]{0,4}$")))
{
e.Handled = true;
}
}
That will allow any number of 1 to 4 digit hex values followed by a comma then followed by 0 to 4 more hex digits. That means that 123,456, is valid, but you need that to be valid to allow the user to type in the comma and continue.
An alternative is to wait and validate after the user enters a value and presses some type of submit button. Then you could change the expression to not allow blank values or trailing commas by changing the {0,4} to {1,4}.
Note: this assumes the user only types characters at the end of the text box if they move the cursor around you'll have to take that into account. Also selecting text and replacing it and copy-and-paste actions would also be problematic.
This should be self explanatory. I am trying to detect if the first char of the string foo is a negative sign '-'. This is just a test code to test it.
private void button1_Click(object sender, EventArgs e)
{
string foo = textBox1.Text;
bool negativeValue = foo[1]==('-');
//bool negativeValue = foo[1].Equals ('-');
if (negativeValue == true)
{
label1.Text = "First char is negative !";
}
else if (negativeValue == false)
{
label1.Text = "First char is not negative !";
}
}
The result is always false even if the first char in the text box is '-'. Why?
Index lookup in C# is zero-based. So you should call:
foo[0] == ('-')
Using 1 will lookup the second character.
EDIT: Also as an alternative (and perhaps more clear) you can always use:
foo.StartsWith("-")
That should work no matter how inebriated you are. :)
(Also, consider trimming the text input if you want to avoid excessive/accidental preceding spaces from user input)
You are using wrong index.With 1 you are actually referring to 2nd character
Use 0
bool negativeValue = foo[0]==('-');
I am having quite a hard time with my C# Application's textbox validation. The thing is, the said textbox should only accept decimal values. so it means, there should be no letters or any other symbols aside from the '.' symbol. The letter filter, i can handle. However, i don't exactly know how I can manage to filter the number of '.' that the textbox should accept. If anybody has any idea how to do this, please give me an idea.
Thank you very much :)
decimal value;
bool isValid = decimal.TryParse(textBox.Text, out value);
if (!isValid)
{
throw new ArgumentException("Input must be a decimal value");
}
this should work!!!
modified for just one decimal
private void txtType_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Back || (e.KeyChar == (char)'.') && !(sender as TextBox).Text.Contains("."))
{
return;
}
decimal isNumber = 0;
e.Handled = !decimal.TryParse(e.KeyChar.ToString(), out isNumber);
}
Use regex validation:
^([0-9]*|\d*\.\d{1}?\d*)$
This site has a library of regex validation (including numeric related) that you'll find useful:
http://regexlib.com/Search.aspx?k=decimal&c=-1&m=-1&ps=20
Just a thought: if you are monitoring the decimal places, simply keep a bool flag in your control to say "I've already had a dot"; subsequent dots are invalid.
Alternatively, when checking for decimal places, you can use Contains:
if (textbox.Text.Contains("."))
Also, review this sample available on MSDN (NumericTextBox):
http://msdn.microsoft.com/en-us/library/ms229644(VS.80).aspx
Use a MaskedTextBox instead and set the mask to only accept decimals.