From 9ee4aeae32d341029bd841a2523809d66d1b32a1 Mon Sep 17 00:00:00 2001 From: Magnus Lindhe Date: Fri, 11 Oct 2019 15:39:52 +0200 Subject: [PATCH] (GH-3376) Improved handling for percent & permille for NumericUpDown --- src/MahApps.Metro/Controls/NumericUpDown.cs | 73 ++++++++++++------- .../Tests/NumericUpDownTests.cs | 54 ++++++++++++++ 2 files changed, 99 insertions(+), 28 deletions(-) diff --git a/src/MahApps.Metro/Controls/NumericUpDown.cs b/src/MahApps.Metro/Controls/NumericUpDown.cs index 478a7cf96f..080ecfc648 100644 --- a/src/MahApps.Metro/Controls/NumericUpDown.cs +++ b/src/MahApps.Metro/Controls/NumericUpDown.cs @@ -190,6 +190,7 @@ private static void InterceptManualEnterChangedCallback(DependencyObject depende //private static readonly Regex RegexNumber = new Regex(@"[-+]?(?.*))?\}", RegexOptions.Compiled); private const double DefaultInterval = 1d; private const int DefaultDelay = 500; @@ -1016,44 +1017,60 @@ private string FormattedValue(double? newValue, string format, CultureInfo cultu format = format.Replace("{}", string.Empty); if (!string.IsNullOrWhiteSpace(format)) { - var match = RegexStringFormatHexadecimal.Match(format); - if (match.Success) + if(TryFormatHexadecimal(newValue, format, culture, out string hexValue)) { - if (match.Groups["simpleHEX"].Success) - { - // HEX DOES SUPPORT INT ONLY. - return ((int)newValue.Value).ToString(match.Groups["simpleHEX"].Value, culture); - } - - if (match.Groups["complexHEX"].Success) - { - return string.Format(culture, match.Groups["complexHEX"].Value, (int)newValue.Value); - } + return hexValue; } else { - var value = newValue.Value; - - if (format.ToUpper().Contains("P") || format.Contains("%")) - { - value = value / 100d; - } - else if (format.Contains("‰")) - { - value = value / 1000d; - } - - if (!format.Contains("{")) + var match = RegexStringFormat.Match(format); + if (match.Success) { - // then we may have a StringFormat of e.g. "N0" - return value.ToString(format, culture); + // we have a format template such as "{0:N0}" + return string.Format(culture, format, ConvertStringFormatValue(newValue.Value, match.Groups["format"].Value)); } - - return string.Format(culture, format, value); + // we have a format such as "N0" + var value = ConvertStringFormatValue(newValue.Value, format); + return value.ToString(format, culture); } } return newValue.Value.ToString(culture); + } + + private static double ConvertStringFormatValue(double value, string format) + { + if (format.ToUpper().Contains("P") || format.Contains("%")) + { + value /= 100d; + } + else if (format.Contains("‰")) + { + value /= 1000d; + } + return value; + } + + private bool TryFormatHexadecimal(double? newValue, string format, CultureInfo culture, out string output) + { + var match = RegexStringFormatHexadecimal.Match(format); + if (match.Success) + { + if (match.Groups["simpleHEX"].Success) + { + // HEX DOES SUPPORT INT ONLY. + output = ((int)newValue.Value).ToString(match.Groups["simpleHEX"].Value, culture); + return true; + } + + if (match.Groups["complexHEX"].Success) + { + output = string.Format(culture, match.Groups["complexHEX"].Value, (int)newValue.Value); + return true; + } + } + output = null; + return false; } private ScrollViewer TryFindScrollViewer() diff --git a/src/Mahapps.Metro.Tests/Tests/NumericUpDownTests.cs b/src/Mahapps.Metro.Tests/Tests/NumericUpDownTests.cs index daafc637c9..d99b4f2944 100644 --- a/src/Mahapps.Metro.Tests/Tests/NumericUpDownTests.cs +++ b/src/Mahapps.Metro.Tests/Tests/NumericUpDownTests.cs @@ -124,6 +124,12 @@ public async Task ShouldConvertTextInputWithStringFormat() SetText(textBox, "200.00"); Assert.Equal(200d, window.TheNUD.Value); Assert.Equal("200.00 cm", textBox.Text); + + // GH-3551 + window.TheNUD.StringFormat = "{}{0}mmHg"; + SetText(textBox, "15"); + Assert.Equal(15, window.TheNUD.Value); + Assert.Equal("15mmHg", textBox.Text); } [Fact] @@ -195,6 +201,54 @@ public async Task ShouldConvertTextInputWithPercentStringFormat() SetText(textBox, "-0.39678"); Assert.Equal(-0.39678d, window.TheNUD.Value); Assert.Equal("-0.4 %", textBox.Text); + + window.TheNUD.StringFormat = "{}{0:0.0%}"; + SetText(textBox, "1"); + Assert.Equal(1, window.TheNUD.Value); + Assert.Equal("1.0%", textBox.Text); + + window.TheNUD.StringFormat = "{0:0.0%}"; + SetText(textBox, "1"); + Assert.Equal(1, window.TheNUD.Value); + Assert.Equal("1.0%", textBox.Text); + + window.TheNUD.StringFormat = "0.0%"; + SetText(textBox, "1"); + Assert.Equal(1, window.TheNUD.Value); + Assert.Equal("1.0%", textBox.Text); + + window.TheNUD.StringFormat = "{}{0:0.0‰}"; + SetText(textBox, "1"); + Assert.Equal(1, window.TheNUD.Value); + Assert.Equal("1.0‰", textBox.Text); + + window.TheNUD.StringFormat = "{0:0.0‰}"; + SetText(textBox, "1"); + Assert.Equal(1, window.TheNUD.Value); + Assert.Equal("1.0‰", textBox.Text); + + window.TheNUD.StringFormat = "0.0‰"; + SetText(textBox, "1"); + Assert.Equal(1, window.TheNUD.Value); + Assert.Equal("1.0‰", textBox.Text); + + // GH-3376 Case 3 + window.TheNUD.StringFormat = "{0:0.0000}%"; + SetText(textBox, "0.25"); + Assert.Equal(0.25, window.TheNUD.Value); + Assert.Equal("0.2500%", textBox.Text); + + // GH-3376 Case 4 + window.TheNUD.StringFormat = "{0:0.0000}‰"; + SetText(textBox, "0.25"); + Assert.Equal(0.25, window.TheNUD.Value); + Assert.Equal("0.2500‰", textBox.Text); + + // GH-3376#issuecomment-472324787 + window.TheNUD.StringFormat = "{}{0:G3} mPa·s"; + SetText(textBox, "0.986"); + Assert.Equal(0.986, window.TheNUD.Value); + Assert.Equal("0.986 mPa·s", textBox.Text); } [Fact]