I am trying to make a Numeric only TextBox
in WPF and I have this code for it:
void NumericTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
e.Handled = !IsValidInput(e.Text);
}
private bool IsValidInput(string p)
{
switch (this.Type)
{
case NumericTextBoxType.Float:
return Regex.Match(p, "^[0-9]*[.][0-9]*$").Success;
case NumericTextBoxType.Integer:
default:
return Regex.Match(p, "^[0-9]*$").Success;
}
}
// And also this!
public enum NumericTextBoxType
{
Integer = 0,
Float = 1
}
When I set the type to Integer, it works well, but for Float, it does not.
I can use so many NumericTextBox
controls out there, but I was wondering why this one is not working?
[0-9]+|[0-9]+). This regular expression matches an optional sign, that is either followed by zero or more digits followed by a dot and one or more digits (a floating point number with optional integer part), or that is followed by one or more digits (an integer).
The [0-9] expression is used to find any character between the brackets. The digits inside the brackets can be any numbers or span of numbers from 0 to 9. Tip: Use the [^0-9] expression to find any character that is NOT a digit.
$ means "Match the end of the string" (the position after the last character in the string). Both are called anchors and ensure that the entire string is matched instead of just a substring.
I urge you to use Double.TryParse()
method instead of regex validation. Using TryParse()
let your application to be a bit more universal in terms of culture. When current culture changes, TryParse()
will parse with no problem. Also TryParse()
methods believed to have no bugs as they were tested by .net community.
But in case of regex your should change your validation expression hence it could be no relevant to new culture.
You can rewrite code like this:
private bool IsValidInput(string p)
{
switch (this.Type)
{
case NumericTextBoxType.Float:
double doubleResult;
return double.TryParse(p, out doubleResult);
case NumericTextBoxType.Integer:
default:
int intResult;
return int.TryParse(p, out intResult);
}
}
You can even add your own extension methods to make parsing part more elegant.
public static double? TryParseInt(this string source)
{
double result;
return double.TryParse(source, out result) ? result : (double?)null;
}
// usage
bool ok = source.TryParseInt().HasValue;
Try this:
@"^[0-9]*(?:\.[0-9]*)?$"
You need to escape the period. And making the period and decimal part optional is probably a good idea.
If you need to handle negative values you can add -?
before the first [0-9]
in each pattern.
Update
Tested as follows:
var regex = new Regex(@"^[0-9]*(?:\.[0-9]*)?$");
Console.WriteLine(new bool[] {regex.IsMatch("blah"),
regex.IsMatch("12"),
regex.IsMatch(".3"),
regex.IsMatch("12.3"),
regex.IsMatch("12.3.4")});
results in
False
True
True
True
False
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With