C
C#3w ago
Samuel

Decimal in clamped TextBox

I'm implementing a numerical TextBox that may clamp entered values between a min and max value. I achieved this by overriding the MetaData for the Text property with a TwoWay binding by default and an OnTextChanged handler. One of the hurdles along the way was partially entered values such as -, 0., 1.3, etc. I overcame this with a regex. The issue I have is that I'm unable to enter a decimal into the TextBox despite being allowed by the regex ^(-?\d+\.|-0?)$. Here is my on changed handler.
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var s = (string)e.NewValue;
var regex = new Regex(@"^(-?\d+\.|-0?)$");
if (string.IsNullOrEmpty(s) || regex.Match(s).Success)
return;

if (double.TryParse((string)e.NewValue, out var oldValue))
{
if (!(bool)d.GetValue(EnforceRangeProperty))
return;

var min = (double)d.GetValue(MinProperty);
var max = (double)d.GetValue(MaxProperty);

var newValue = Math.Max(min, oldValue);
newValue = Math.Min(max, newValue);

// ReSharper disable once CompareOfFloatsByEqualityOperator
if (newValue == oldValue)
return;

d.SetValue(TextProperty, newValue.ToString(CultureInfo.InvariantCulture));
return;
}

// If we can't parse the text, revert to the old value.
d.SetValue(TextProperty, (string)e.OldValue);
}
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var s = (string)e.NewValue;
var regex = new Regex(@"^(-?\d+\.|-0?)$");
if (string.IsNullOrEmpty(s) || regex.Match(s).Success)
return;

if (double.TryParse((string)e.NewValue, out var oldValue))
{
if (!(bool)d.GetValue(EnforceRangeProperty))
return;

var min = (double)d.GetValue(MinProperty);
var max = (double)d.GetValue(MaxProperty);

var newValue = Math.Max(min, oldValue);
newValue = Math.Min(max, newValue);

// ReSharper disable once CompareOfFloatsByEqualityOperator
if (newValue == oldValue)
return;

d.SetValue(TextProperty, newValue.ToString(CultureInfo.InvariantCulture));
return;
}

// If we can't parse the text, revert to the old value.
d.SetValue(TextProperty, (string)e.OldValue);
}
What changes can I make to allow for the entry of a decimal point? Edit: I've also realised that I cannot enter -0, subsequently -0.
7 Replies
HtmlCompiler
HtmlCompiler3w ago
(pls don't create a regex everytime the method is called 😐 im not sure i would even use a regex here)
Samuel
SamuelOP3w ago
I only included it in the method for clarity I'm open to alternatives to a regex but please keep responses related to the asked question
HtmlCompiler
HtmlCompiler3w ago
to me double.TryParse would be enough (although i would explicitly pass the culture) if you had put var regex in a comment i would have understood it was not initialized in this context also code is exiting on regex.Success, is it missing a == false
Samuel
SamuelOP3w ago
TryParse is not sufficient. For example, if you user starts to enter a negative number, the parsing will fail, and will be reverted to an earlier value. Also, parsing values such as 0., -1. or 123. will parse successfully and remove the decimal
HtmlCompiler
HtmlCompiler3w ago
ok still, what about this:
- if (string.IsNullOrEmpty(s) || regex.Match(s).Success)
+ if (string.IsNullOrEmpty(s) || regex.Match(s).Success == false)
return;
- if (string.IsNullOrEmpty(s) || regex.Match(s).Success)
+ if (string.IsNullOrEmpty(s) || regex.Match(s).Success == false)
return;
Samuel
SamuelOP3w ago
Then no valid entries would be parsed
HtmlCompiler
HtmlCompiler3w ago
haha my fault i misread the regex, im sick today so regex is not blocking 1.23 at this point the next [possible] culprit is double.TryParse and the culture question i don't know where you are, but this: 1.23 smells of invariant culture
Want results from more Discord servers?
Add your server