Skip to content

Commit

Permalink
(MahAppsGH-3665) Fix NumericUpDown decimal places replace with 0 in p…
Browse files Browse the repository at this point in the history
…ersian culture

We need to use a dynamic Regex for the number input instead a static one. So we must look for the NumberFormat.NumberDecimalSeparator and NumberFormat.NumberGroupSeparator and build a new Regex if the Culture was changed.

Closes MahApps#3665
  • Loading branch information
punker76 authored and amkuchta committed Nov 19, 2019
1 parent 60804b3 commit e7a65ad
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 4 deletions.
17 changes: 13 additions & 4 deletions src/MahApps.Metro/Controls/NumericUpDown.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ public class NumericUpDown : Control
if (e.NewValue != e.OldValue)
{
var numUpDown = (NumericUpDown)o;
numUpDown.regexNumber = null;
numUpDown.OnValueChanged(numUpDown.Value, numUpDown.Value);
}
}));
Expand Down Expand Up @@ -187,7 +188,8 @@ private static void InterceptManualEnterChangedCallback(DependencyObject depende
}

private static readonly Regex RegexStringFormatHexadecimal = new Regex(@"^(?<complexHEX>.*{\d:X\d+}.*)?(?<simpleHEX>X\d+)?$", RegexOptions.Compiled);
private static readonly Regex RegexNumber = new Regex(@"[-+]?(?<![0-9][.,])[.,]?[0-9]+(?:[.,\s][0-9]+)*[.,]?[0-9]?(?:[eE][-+]?[0-9]+)?(?!\.[0-9])", RegexOptions.Compiled);
private const string RawRegexNumberString = @"[-+]?(?<![0-9][<DecimalSeparator><GroupSeparator>])[<DecimalSeparator><GroupSeparator>]?[0-9]+(?:[<DecimalSeparator><GroupSeparator>\s][0-9]+)*[<DecimalSeparator><GroupSeparator>]?[0-9]?(?:[eE][-+]?[0-9]+)?(?!\.[0-9])";
private Regex regexNumber = null;
private static readonly Regex RegexHexadecimal = new Regex(@"^([a-fA-F0-9]{1,2}\s?)+$", RegexOptions.Compiled);
private static readonly Regex RegexStringFormat = new Regex(@"\{0\s*(:(?<format>.*))?\}", RegexOptions.Compiled);

Expand Down Expand Up @@ -1282,7 +1284,7 @@ private bool ValidateText(string text, out double convertedValue)
|| this.ParsingNumberStyle.HasFlag(NumberStyles.AllowHexSpecifier)
|| this.ParsingNumberStyle == NumberStyles.HexNumber;

var number = TryGetNumberFromText(text, isHex);
var number = this.TryGetNumberFromText(text, isHex);

// If we are only accepting numbers then attempt to parse as an integer.
if (isNumeric)
Expand Down Expand Up @@ -1325,15 +1327,22 @@ private bool ConvertNumber(string text, out double convertedValue)
return true;
}

private static string TryGetNumberFromText(string text, bool isHex)
private string TryGetNumberFromText(string text, bool isHex)
{
if (isHex)
{
var hexMatches = RegexHexadecimal.Matches(text);
return hexMatches.Count > 0 ? hexMatches[0].Value : text;
}

var matches = RegexNumber.Matches(text);
if (this.regexNumber == null)
{
this.regexNumber = new Regex(RawRegexNumberString.Replace("<DecimalSeparator>", this.SpecificCultureInfo.NumberFormat.NumberDecimalSeparator)
.Replace("<GroupSeparator>", this.SpecificCultureInfo.NumberFormat.NumberGroupSeparator),
RegexOptions.Compiled);
}

var matches = this.regexNumber.Matches(text);
return matches.Count > 0 ? matches[0].Value : text;
}
}
Expand Down
31 changes: 31 additions & 0 deletions src/Mahapps.Metro.Tests/Tests/NumericUpDownTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,37 @@ public async Task ShouldConvertDecimalTextInput()
Assert.Equal(0.0115d, window.TheNUD.Value);
}

[Fact]
[DisplayTestMethodName]
public async Task ShouldConvertDecimalTextInputWithSpecialCulture()
{
await TestHost.SwitchToAppThread();
var window = await WindowHelpers.CreateInvisibleWindowAsync<NumericUpDownWindow>().ConfigureAwait(false);
await TestHost.SwitchToAppThread();

var textBox = window.TheNUD.FindChild<TextBox>(string.Empty);
Assert.NotNull(textBox);

window.TheNUD.NumericInputMode = NumericInput.Decimal;

window.TheNUD.Culture = CultureInfo.GetCultureInfo("fa-IR");

SetText(textBox, "42");
Assert.Equal(42d, window.TheNUD.Value);

SetText(textBox, "42/751");
Assert.Equal(42.751d, window.TheNUD.Value);

SetText(textBox, "/");
Assert.Equal(0d, window.TheNUD.Value);

SetText(textBox, "/9");
Assert.Equal(0.9d, window.TheNUD.Value);

SetText(textBox, "/0115");
Assert.Equal(0.0115d, window.TheNUD.Value);
}

[Fact]
[DisplayTestMethodName]
public async Task ShouldConvertNumericTextInput()
Expand Down

0 comments on commit e7a65ad

Please sign in to comment.