diff --git a/Microsoft.Toolkit.Uwp.UI/Converters/StringFormatConverter.cs b/Microsoft.Toolkit.Uwp.UI/Converters/StringFormatConverter.cs
index cb01f422c3f..53dfcf868f2 100644
--- a/Microsoft.Toolkit.Uwp.UI/Converters/StringFormatConverter.cs
+++ b/Microsoft.Toolkit.Uwp.UI/Converters/StringFormatConverter.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Globalization;
using Windows.UI.Xaml.Data;
namespace Microsoft.Toolkit.Uwp.UI.Converters
@@ -12,13 +13,26 @@ namespace Microsoft.Toolkit.Uwp.UI.Converters
///
public class StringFormatConverter : IValueConverter
{
+ ///
+ /// Gets or sets the CultureInfo to make converter culture sensitive. The default value is
+ ///
+ public CultureInfo CultureInfo { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public StringFormatConverter()
+ {
+ CultureInfo = CultureInfo.CurrentCulture;
+ }
+
///
/// Return the formatted string version of the source object.
///
/// Object to transform to string.
/// The type of the target property, as a type reference
/// An optional parameter to be used in the string.Format method.
- /// The language of the conversion (not used).
+ /// The language of the conversion. If language is null or empty then will be used.
/// Formatted string.
public object Convert(object value, Type targetType, object parameter, string language)
{
@@ -27,20 +41,13 @@ public object Convert(object value, Type targetType, object parameter, string la
return null;
}
- if (parameter == null)
+ string formatParameter = parameter as string;
+ if (formatParameter == null)
{
return value;
}
- try
- {
- return string.Format((string)parameter, value);
- }
- catch
- {
- }
-
- return value;
+ return FormatToString(value, formatParameter, GetCultureInfoOrDefault(language, () => GetDefaultCultureInfo()));
}
///
@@ -55,5 +62,53 @@ public object ConvertBack(object value, Type targetType, object parameter, strin
{
throw new NotImplementedException();
}
+
+ private object FormatToString(object value, string parameter, CultureInfo cultureInfo)
+ {
+ try
+ {
+ return string.Format(cultureInfo, parameter, value);
+ }
+ catch
+ {
+ return value;
+ }
+ }
+
+ private CultureInfo GetCultureInfoOrDefault(string language, Func getDefaultCultureInfo)
+ {
+ CultureInfo cultureInfo;
+ if (!TryGetCultureInfo(language, out cultureInfo))
+ {
+ cultureInfo = getDefaultCultureInfo();
+ }
+
+ return cultureInfo;
+ }
+
+ private bool TryGetCultureInfo(string language, out CultureInfo cultureInfo)
+ {
+ cultureInfo = null;
+ if (string.IsNullOrEmpty(language))
+ {
+ return false;
+ }
+
+ try
+ {
+ cultureInfo = CultureInfo.GetCultureInfo(language);
+
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ private CultureInfo GetDefaultCultureInfo()
+ {
+ return CultureInfo ?? CultureInfo.InvariantCulture;
+ }
}
}
\ No newline at end of file
diff --git a/UnitTests/UnitTests.UWP/Converters/Test_StringFormatConverter.cs b/UnitTests/UnitTests.UWP/Converters/Test_StringFormatConverter.cs
index 8bf74420b30..51d3ece8d80 100644
--- a/UnitTests/UnitTests.UWP/Converters/Test_StringFormatConverter.cs
+++ b/UnitTests/UnitTests.UWP/Converters/Test_StringFormatConverter.cs
@@ -5,59 +5,157 @@
using Microsoft.Toolkit.Uwp.UI.Converters;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
+using System.Globalization;
namespace UnitTests.Converters
{
[TestClass]
public class Test_StringFormatConverter
{
- private static readonly object NullString = null;
+ private const string NullLanguage = null;
+
+ private static readonly CultureInfo ConverterCultureInfo = new CultureInfo("pl-pl");
+ private static readonly object NullString = null;
private static readonly object NotEmptyString = "Hello, world";
private static readonly DateTime Date = DateTime.Now;
+ private static readonly decimal Amount = 333.4m;
[TestCategory("Converters")]
[TestMethod]
- public void WhenValueIsNull_ThenReturnNull()
+ [DataRow(NullLanguage)]
+ [DataRow("en-us")]
+ public void WhenValueIsNull_ThenReturnNull(string language)
{
var converter = new StringFormatConverter();
- var result = converter.Convert(NullString, typeof(string), NullString, "en-us");
+ var result = converter.Convert(NullString, typeof(string), NullString, language);
Assert.IsNull(result);
}
[TestCategory("Converters")]
[TestMethod]
- public void WhenValueExistsAndParameterIsNull_ThenReturnValue()
+ [DataRow(NullLanguage)]
+ [DataRow("en-us")]
+ public void WhenValueExistsAndParameterIsNull_ThenReturnValue(string language)
{
var converter = new StringFormatConverter();
- var result = converter.Convert(NotEmptyString, typeof(string), NullString, "en-us");
+ var result = converter.Convert(NotEmptyString, typeof(string), NullString, language);
Assert.AreEqual(NotEmptyString, result);
}
[TestCategory("Converters")]
[TestMethod]
- public void WhenParameterIsTimeFormat_ThenReturnValueOfTimeFormat()
+ [DataRow(NullLanguage)]
+ [DataRow("en-us")]
+ public void WhenParameterIsInvalidFormat_ThenReturnValue(string language)
{
- var converter = new StringFormatConverter();
- var result = converter.Convert(Date, typeof(string), "{0:HH:mm}", "en-us");
- Assert.AreEqual(Date.ToString("HH:mm"), result);
+ var converter = new StringFormatConverter()
+ {
+ CultureInfo = ConverterCultureInfo
+ };
+ var result = converter.Convert(Date, typeof(string), "{1:}", language);
+ Assert.AreEqual(Date, result);
}
[TestCategory("Converters")]
[TestMethod]
- public void WhenParameterIsInvalidFormat_ThenReturnValue()
+ [DataRow(NullLanguage)]
+ [DataRow("en-us")]
+ public void WhenParameterIsNotAString_ThenReturnValue(string language)
{
- var converter = new StringFormatConverter();
- var result = converter.Convert(Date, typeof(string), "{1:}", "en-us");
- Assert.AreEqual(Date, result);
+ var converter = new StringFormatConverter()
+ {
+ CultureInfo = ConverterCultureInfo
+ };
+ var result = converter.Convert(NotEmptyString, typeof(string), 172, language);
+ Assert.AreEqual(NotEmptyString, result);
+ }
+
+ [TestCategory("Converters")]
+ [TestMethod]
+ [DataRow("{0:ddd d MMM}", "ddd d MMM")]
+ [DataRow("{0:HH:mm}", "HH:mm")]
+ [DataRow("{0:hh:mm:ss tt}", "hh:mm:ss tt")]
+ public void WhenValueIsDateTimeAndLanguageIsUnknownAndCultureInfoIsNotSet_ThenReturnValueOfTimeInInvariantCultureFormat(string converterParameter, string expectedFormat)
+ {
+ var converter = new StringFormatConverter()
+ {
+ CultureInfo = null
+ };
+ var result = converter.Convert(Date, typeof(string), converterParameter, NullLanguage);
+ Assert.AreEqual(Date.ToString(expectedFormat, CultureInfo.InvariantCulture), result);
}
[TestCategory("Converters")]
[TestMethod]
- public void WhenParameterIsNotAString_ThenReturnValue()
+ [DataRow("{0:ddd d MMM}", "ddd d MMM")]
+ [DataRow("{0:HH:mm}", "HH:mm")]
+ [DataRow("{0:hh:mm:ss tt}", "hh:mm:ss tt")]
+ public void WhenValueIsDateTimeAndLanguageIsUnknownAndCultureInfoIsSet_ThenReturnValueOfTimeInConverterCultureInfoFormat(string converterParameter, string expectedFormat)
{
- var converter = new StringFormatConverter();
- var result = converter.Convert(NotEmptyString, typeof(string), 172, "en-us");
- Assert.AreEqual(NotEmptyString, result);
+ var converter = new StringFormatConverter()
+ {
+ CultureInfo = ConverterCultureInfo
+ };
+ var result = converter.Convert(Date, typeof(string), converterParameter, NullLanguage);
+ Assert.AreEqual(Date.ToString(expectedFormat, ConverterCultureInfo), result);
+ }
+
+ [TestCategory("Converters")]
+ [TestMethod]
+ [DataRow("en-us", "{0:ddd d MMM}", "ddd d MMM")]
+ [DataRow("en-us", "{0:HH:mm}", "HH:mm")]
+ [DataRow("en-us", "{0:hh:mm:ss tt}", "hh:mm:ss tt")]
+ public void WhenValueIsDateTimeAndLanguageIsWellKnownAndCultureInfoIsSet_ThenReturnValueOfTimeInLanguageCultureFormat(string language, string converterParameter, string expectedFormat)
+ {
+ var converter = new StringFormatConverter()
+ {
+ CultureInfo = ConverterCultureInfo,
+ };
+ var result = converter.Convert(Date, typeof(string), converterParameter, language);
+ Assert.AreEqual(Date.ToString(expectedFormat, CultureInfo.GetCultureInfo(language)), result);
+ }
+
+ [TestCategory("Converters")]
+ [TestMethod]
+ [DataRow("{0:C2}", "C2")]
+ [DataRow("{0:E}", "E")]
+ public void WhenValueIsDecimalAndLanguageIsUnknownAndCultureInfoIsNotSet_ThenReturnValueOfDecimalInInvariantCultureFormat(string converterParameter, string expectedFormat)
+ {
+ var converter = new StringFormatConverter()
+ {
+ CultureInfo = null
+ };
+ var result = converter.Convert(Amount, typeof(string), converterParameter, NullLanguage);
+ Assert.AreEqual(Amount.ToString(expectedFormat, CultureInfo.InvariantCulture), result);
}
+
+ [TestCategory("Converters")]
+ [TestMethod]
+ [DataRow("{0:C2}", "C2")]
+ [DataRow("{0:E}", "E")]
+ public void WhenValueIsDecimalAndLanguageIsUnknownAndCultureInfoIsSet_ThenReturnValueOfDecimalInConverterCultureInfoFormat(string converterParameter, string expectedFormat)
+ {
+ var converter = new StringFormatConverter()
+ {
+ CultureInfo = ConverterCultureInfo
+ };
+ var result = converter.Convert(Amount, typeof(string), converterParameter, NullLanguage);
+ Assert.AreEqual(Amount.ToString(expectedFormat, ConverterCultureInfo), result);
+ }
+
+ [TestCategory("Converters")]
+ [TestMethod]
+ [DataRow("en-us", "{0:C2}", "C2")]
+ [DataRow("en-us", "{0:E}", "E")]
+ [DataRow("fr-FR", "{0:E}", "E")]
+ public void WhenValueIsDecimalAndLanguageIsWellKnownAndCultureInfoIsSet_ThenReturnValueOfDecimalInLanguageCultureFormat(string language, string converterParameter, string expectedFormat)
+ {
+ var converter = new StringFormatConverter()
+ {
+ CultureInfo = ConverterCultureInfo,
+ };
+ var result = converter.Convert(Amount, typeof(string), converterParameter, language);
+ Assert.AreEqual(Amount.ToString(expectedFormat, CultureInfo.GetCultureInfo(language)), result);
+ }
}
}
\ No newline at end of file