diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index 06a03a05f390..2cae3af98440 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -212,7 +212,29 @@ private static string FormatShortValueCore(short value, CultureInfo? culture) /// /// The formatted value. [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] - public static string FormatValue(float value, CultureInfo? culture = null) => FormatFloatValueCore(value, culture); + public static string FormatValue(float value, CultureInfo? culture = null) => FormatFloatValueCore(value, culture, format: null); + + /// + /// Formats the provided for inclusion in an attribute. + /// + /// The value to format. + /// + /// The to use while formatting. Defaults to . + /// + /// The format to use. Provided to . + /// The formatted value. + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] + public static string FormatValue(float value, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format, CultureInfo? culture = null) => FormatFloatValueCore(value, culture, format); + + private static string FormatFloatValueCore(float value, CultureInfo? culture, string? format) + { + if (format != null) + { + return value.ToString(format, culture ?? CultureInfo.CurrentCulture); + } + + return value.ToString(culture ?? CultureInfo.CurrentCulture); + } private static string FormatFloatValueCore(float value, CultureInfo? culture) { @@ -228,7 +250,34 @@ private static string FormatFloatValueCore(float value, CultureInfo? culture) /// /// The formatted value. [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] - public static string? FormatValue(float? value, CultureInfo? culture = null) => FormatNullableFloatValueCore(value, culture); + public static string? FormatValue(float? value, CultureInfo? culture = null) => FormatNullableFloatValueCore(value, culture, format: null); + + /// + /// Formats the provided for inclusion in an attribute. + /// + /// The value to format. + /// + /// The to use while formatting. Defaults to . + /// + /// The format to use. Provided to . + /// The formatted value. + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] + public static string? FormatValue(float? value, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format, CultureInfo? culture = null) => FormatNullableFloatValueCore(value, culture, format); + + private static string? FormatNullableFloatValueCore(float? value, CultureInfo? culture, string? format) + { + if (value == null) + { + return null; + } + + if (format != null) + { + return value.Value.ToString(format, culture ?? CultureInfo.CurrentCulture); + } + + return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); + } private static string? FormatNullableFloatValueCore(float? value, CultureInfo? culture) { @@ -249,7 +298,29 @@ private static string FormatFloatValueCore(float value, CultureInfo? culture) /// /// The formatted value. [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] - public static string? FormatValue(double value, CultureInfo? culture = null) => FormatDoubleValueCore(value, culture); + public static string? FormatValue(double value, CultureInfo? culture = null) => FormatDoubleValueCore(value, culture, format: null); + + /// + /// Formats the provided for inclusion in an attribute. + /// + /// The value to format. + /// + /// The to use while formatting. Defaults to . + /// + /// The format to use. Provided to . + /// The formatted value. + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] + public static string? FormatValue(double value, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format, CultureInfo? culture = null) => FormatDoubleValueCore(value, culture, format); + + private static string FormatDoubleValueCore(double value, CultureInfo? culture, string? format) + { + if (format != null) + { + return value.ToString(format, culture ?? CultureInfo.CurrentCulture); + } + + return value.ToString(culture ?? CultureInfo.CurrentCulture); + } private static string FormatDoubleValueCore(double value, CultureInfo? culture) { @@ -265,7 +336,19 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture) /// /// The formatted value. [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] - public static string? FormatValue(double? value, CultureInfo? culture = null) => FormatNullableDoubleValueCore(value, culture); + public static string? FormatValue(double? value, CultureInfo? culture = null) => FormatNullableDoubleValueCore(value, culture, format: null); + + /// + /// Formats the provided for inclusion in an attribute. + /// + /// The value to format. + /// + /// The to use while formatting. Defaults to . + /// + /// The format to use. Provided to . + /// The formatted value. + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] + public static string? FormatValue(double? value, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format, CultureInfo? culture = null) => FormatNullableDoubleValueCore(value, culture, format); private static string? FormatNullableDoubleValueCore(double? value, CultureInfo? culture) { @@ -277,6 +360,21 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture) return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); } + private static string? FormatNullableDoubleValueCore(double? value, CultureInfo? culture, string? format) + { + if (value == null) + { + return null; + } + + if (format != null) + { + return value.Value.ToString(format, culture ?? CultureInfo.CurrentCulture); + } + + return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); + } + /// /// Formats the provided for inclusion in an attribute. /// @@ -286,13 +384,35 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture) /// /// The formatted value. [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] - public static string FormatValue(decimal value, CultureInfo? culture = null) => FormatDecimalValueCore(value, culture); + public static string FormatValue(decimal value, CultureInfo? culture = null) => FormatDecimalValueCore(value, culture, format: null); + + /// + /// Formats the provided for inclusion in an attribute. + /// + /// The value to format. + /// + /// The to use while formatting. Defaults to . + /// + /// The format to use. Provided to . + /// The formatted value. + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] + public static string FormatValue(decimal value, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format, CultureInfo? culture = null) => FormatDecimalValueCore(value, culture, format); private static string FormatDecimalValueCore(decimal value, CultureInfo? culture) { return value.ToString(culture ?? CultureInfo.CurrentCulture); } + private static string FormatDecimalValueCore(decimal value, CultureInfo? culture, string? format) + { + if (format != null) + { + return value.ToString(format, culture ?? CultureInfo.CurrentCulture); + } + + return value.ToString(culture ?? CultureInfo.CurrentCulture); + } + /// /// Formats the provided as a . /// @@ -302,7 +422,19 @@ private static string FormatDecimalValueCore(decimal value, CultureInfo? culture /// /// The formatted value. [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] - public static string? FormatValue(decimal? value, CultureInfo? culture = null) => FormatNullableDecimalValueCore(value, culture); + public static string? FormatValue(decimal? value, CultureInfo? culture = null) => FormatNullableDecimalValueCore(value, culture, format: null); + + /// + /// Formats the provided as a . + /// + /// The value to format. + /// + /// The to use while formatting. Defaults to . + /// + /// The format to use. Provided to . + /// The formatted value. + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] + public static string? FormatValue(decimal? value, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format, CultureInfo? culture = null) => FormatNullableDecimalValueCore(value, culture, format); private static string? FormatNullableDecimalValueCore(decimal? value, CultureInfo? culture) { @@ -314,6 +446,21 @@ private static string FormatDecimalValueCore(decimal value, CultureInfo? culture return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); } + private static string? FormatNullableDecimalValueCore(decimal? value, CultureInfo? culture, string? format) + { + if (value == null) + { + return null; + } + + if (format != null) + { + return value.Value.ToString(format, culture ?? CultureInfo.CurrentCulture); + } + + return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); + } + /// /// Formats the provided as a . /// @@ -969,9 +1116,16 @@ public static bool TryConvertToNullableFloat(object? obj, CultureInfo? culture, } internal static BindParser ConvertToFloat = ConvertToFloatCore; + internal static BindParserWithFormat ConvertToFloatWithFormat = ConvertToFloatCore; internal static BindParser ConvertToNullableFloat = ConvertToNullableFloatCore; + internal static BindParserWithFormat ConvertToNullableFloatWithFormat = ConvertToNullableFloatCore; private static bool ConvertToFloatCore(object? obj, CultureInfo? culture, out float value) + { + return ConvertToFloatCore(obj, culture, format: null, out value); + } + + private static bool ConvertToFloatCore(object? obj, CultureInfo? culture, string? format, out float value) { var text = (string?)obj; if (string.IsNullOrEmpty(text)) @@ -997,6 +1151,11 @@ private static bool ConvertToFloatCore(object? obj, CultureInfo? culture, out fl } private static bool ConvertToNullableFloatCore(object? obj, CultureInfo? culture, out float? value) + { + return ConvertToNullableFloatCore(obj, culture, format: null, out value); + } + + private static bool ConvertToNullableFloatCore(object? obj, CultureInfo? culture, string? format, out float? value) { var text = (string?)obj; if (string.IsNullOrEmpty(text)) @@ -1046,9 +1205,16 @@ public static bool TryConvertToNullableDouble(object? obj, CultureInfo? culture, } internal static BindParser ConvertToDoubleDelegate = ConvertToDoubleCore; + internal static BindParserWithFormat ConvertToDoubleWithFormat = ConvertToDoubleCore; internal static BindParser ConvertToNullableDoubleDelegate = ConvertToNullableDoubleCore; + internal static BindParserWithFormat ConvertToNullableDoubleWithFormat = ConvertToNullableDoubleCore; private static bool ConvertToDoubleCore(object? obj, CultureInfo? culture, out double value) + { + return ConvertToDoubleCore(obj, culture, format: null, out value); + } + + private static bool ConvertToDoubleCore(object? obj, CultureInfo? culture, string? format, out double value) { var text = (string?)obj; if (string.IsNullOrEmpty(text)) @@ -1074,6 +1240,11 @@ private static bool ConvertToDoubleCore(object? obj, CultureInfo? culture, out d } private static bool ConvertToNullableDoubleCore(object? obj, CultureInfo? culture, out double? value) + { + return ConvertToNullableDoubleCore(obj, culture, format: null, out value); + } + + private static bool ConvertToNullableDoubleCore(object? obj, CultureInfo? culture, string? format, out double? value) { var text = (string?)obj; if (string.IsNullOrEmpty(text)) @@ -1123,9 +1294,16 @@ public static bool TryConvertToNullableDecimal(object? obj, CultureInfo? culture } internal static BindParser ConvertToDecimal = ConvertToDecimalCore; + internal static BindParserWithFormat ConvertToDecimalWithFormat = ConvertToDecimalCore; internal static BindParser ConvertToNullableDecimal = ConvertToNullableDecimalCore; + internal static BindParserWithFormat ConvertToNullableDecimalWithFormat = ConvertToNullableDecimalCore; private static bool ConvertToDecimalCore(object? obj, CultureInfo? culture, out decimal value) + { + return ConvertToDecimalCore(obj, culture, format: null, out value); + } + + private static bool ConvertToDecimalCore(object? obj, CultureInfo? culture, string? format, out decimal value) { var text = (string?)obj; if (string.IsNullOrEmpty(text)) @@ -1145,6 +1323,11 @@ private static bool ConvertToDecimalCore(object? obj, CultureInfo? culture, out } private static bool ConvertToNullableDecimalCore(object? obj, CultureInfo? culture, out decimal? value) + { + return ConvertToNullableDecimalCore(obj, culture, format: null, out value); + } + + private static bool ConvertToNullableDecimalCore(object? obj, CultureInfo? culture, string? format, out decimal? value) { var text = (string?)obj; if (string.IsNullOrEmpty(text)) diff --git a/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs b/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs index 1532ff08b326..e743cce279c2 100644 --- a/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs +++ b/src/Components/Components/src/EventCallbackFactoryBinderExtensions.cs @@ -422,6 +422,28 @@ public static EventCallback CreateBinder( return CreateBinderCoreAsync(factory, receiver, setter, culture, ConvertToFloat); } + /// + /// For internal use only. + /// + /// + /// + /// + /// + /// + /// + /// + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] + public static EventCallback CreateBinder( + this EventCallbackFactory factory, + object receiver, + Action setter, + float existingValue, + string format, + CultureInfo? culture = null) + { + return CreateBinderCore(factory, receiver, setter, culture, format, ConvertToFloatWithFormat); + } + /// /// For internal use only. /// @@ -462,6 +484,28 @@ public static EventCallback CreateBinder( return CreateBinderCoreAsync(factory, receiver, setter, culture, ConvertToNullableFloat); } + /// + /// For internal use only. + /// + /// + /// + /// + /// + /// + /// + /// + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] + public static EventCallback CreateBinder( + this EventCallbackFactory factory, + object receiver, + Action setter, + float? existingValue, + string format, + CultureInfo? culture = null) + { + return CreateBinderCore(factory, receiver, setter, culture, format, ConvertToNullableFloatWithFormat); + } + /// /// For internal use only. /// @@ -502,6 +546,28 @@ public static EventCallback CreateBinder( return CreateBinderCoreAsync(factory, receiver, setter, culture, ConvertToDoubleDelegate); } + /// + /// For internal use only. + /// + /// + /// + /// + /// + /// + /// + /// + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] + public static EventCallback CreateBinder( + this EventCallbackFactory factory, + object receiver, + Action setter, + double existingValue, + string format, + CultureInfo? culture = null) + { + return CreateBinderCore(factory, receiver, setter, culture, format, ConvertToDoubleWithFormat); + } + /// /// For internal use only. /// @@ -542,6 +608,28 @@ public static EventCallback CreateBinder( return CreateBinderCoreAsync(factory, receiver, setter, culture, ConvertToNullableDoubleDelegate); } + /// + /// For internal use only. + /// + /// + /// + /// + /// + /// + /// + /// + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] + public static EventCallback CreateBinder( + this EventCallbackFactory factory, + object receiver, + Action setter, + double? existingValue, + string format, + CultureInfo? culture = null) + { + return CreateBinderCore(factory, receiver, setter, culture, format, ConvertToNullableDoubleWithFormat); + } + /// /// For internal use only. /// @@ -582,6 +670,28 @@ public static EventCallback CreateBinder( return CreateBinderCoreAsync(factory, receiver, setter, culture, ConvertToDecimal); } + /// + /// For internal use only. + /// + /// + /// + /// + /// + /// + /// + /// + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] + public static EventCallback CreateBinder( + this EventCallbackFactory factory, + object receiver, + Action setter, + decimal existingValue, + string format, + CultureInfo? culture = null) + { + return CreateBinderCore(factory, receiver, setter, culture, format, ConvertToDecimalWithFormat); + } + /// /// For internal use only. /// @@ -622,6 +732,28 @@ public static EventCallback CreateBinder( return CreateBinderCoreAsync(factory, receiver, setter, culture, ConvertToNullableDecimal); } + /// + /// For internal use only. + /// + /// + /// + /// + /// + /// + /// + /// + [SuppressMessage("ApiDesign", "RS0026:Do not add multiple public overloads with optional parameters", Justification = "Required to maintain compatibility")] + public static EventCallback CreateBinder( + this EventCallbackFactory factory, + object receiver, + Action setter, + decimal? existingValue, + string format, + CultureInfo? culture = null) + { + return CreateBinderCore(factory, receiver, setter, culture, format, ConvertToNullableDecimalWithFormat); + } + /// /// For internal use only. /// diff --git a/src/Components/Components/src/PublicAPI.Unshipped.txt b/src/Components/Components/src/PublicAPI.Unshipped.txt index 07e51aca6bd3..86029676506f 100644 --- a/src/Components/Components/src/PublicAPI.Unshipped.txt +++ b/src/Components/Components/src/PublicAPI.Unshipped.txt @@ -14,6 +14,18 @@ Microsoft.AspNetCore.Components.Infrastructure.RegisterPersistentComponentStateS Microsoft.AspNetCore.Components.SupplyParameterFromPersistentComponentStateAttribute Microsoft.AspNetCore.Components.SupplyParameterFromPersistentComponentStateAttribute.SupplyParameterFromPersistentComponentStateAttribute() -> void Microsoft.Extensions.DependencyInjection.SupplyParameterFromPersistentComponentStateProviderServiceCollectionExtensions +static Microsoft.AspNetCore.Components.BindConverter.FormatValue(decimal value, string? format, System.Globalization.CultureInfo? culture = null) -> string! +static Microsoft.AspNetCore.Components.BindConverter.FormatValue(decimal? value, string? format, System.Globalization.CultureInfo? culture = null) -> string? +static Microsoft.AspNetCore.Components.BindConverter.FormatValue(double value, string? format, System.Globalization.CultureInfo? culture = null) -> string? +static Microsoft.AspNetCore.Components.BindConverter.FormatValue(double? value, string? format, System.Globalization.CultureInfo? culture = null) -> string? +static Microsoft.AspNetCore.Components.BindConverter.FormatValue(float value, string? format, System.Globalization.CultureInfo? culture = null) -> string! +static Microsoft.AspNetCore.Components.BindConverter.FormatValue(float? value, string? format, System.Globalization.CultureInfo? culture = null) -> string? +static Microsoft.AspNetCore.Components.EventCallbackFactoryBinderExtensions.CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory! factory, object! receiver, System.Action! setter, decimal existingValue, string! format, System.Globalization.CultureInfo? culture = null) -> Microsoft.AspNetCore.Components.EventCallback +static Microsoft.AspNetCore.Components.EventCallbackFactoryBinderExtensions.CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory! factory, object! receiver, System.Action! setter, decimal? existingValue, string! format, System.Globalization.CultureInfo? culture = null) -> Microsoft.AspNetCore.Components.EventCallback +static Microsoft.AspNetCore.Components.EventCallbackFactoryBinderExtensions.CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory! factory, object! receiver, System.Action! setter, double existingValue, string! format, System.Globalization.CultureInfo? culture = null) -> Microsoft.AspNetCore.Components.EventCallback +static Microsoft.AspNetCore.Components.EventCallbackFactoryBinderExtensions.CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory! factory, object! receiver, System.Action! setter, double? existingValue, string! format, System.Globalization.CultureInfo? culture = null) -> Microsoft.AspNetCore.Components.EventCallback +static Microsoft.AspNetCore.Components.EventCallbackFactoryBinderExtensions.CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory! factory, object! receiver, System.Action! setter, float existingValue, string! format, System.Globalization.CultureInfo? culture = null) -> Microsoft.AspNetCore.Components.EventCallback +static Microsoft.AspNetCore.Components.EventCallbackFactoryBinderExtensions.CreateBinder(this Microsoft.AspNetCore.Components.EventCallbackFactory! factory, object! receiver, System.Action! setter, float? existingValue, string! format, System.Globalization.CultureInfo? culture = null) -> Microsoft.AspNetCore.Components.EventCallback static Microsoft.AspNetCore.Components.Infrastructure.RegisterPersistentComponentStateServiceCollectionExtensions.AddPersistentServiceRegistration(Microsoft.Extensions.DependencyInjection.IServiceCollection! services, Microsoft.AspNetCore.Components.IComponentRenderMode! componentRenderMode) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static Microsoft.AspNetCore.Components.Infrastructure.ComponentsMetricsServiceCollectionExtensions.AddComponentsMetrics(Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! static Microsoft.AspNetCore.Components.Infrastructure.ComponentsMetricsServiceCollectionExtensions.AddComponentsTracing(Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! diff --git a/src/Components/Components/test/BindConverterTest.cs b/src/Components/Components/test/BindConverterTest.cs index b18b71dc5684..ed10a4040278 100644 --- a/src/Components/Components/test/BindConverterTest.cs +++ b/src/Components/Components/test/BindConverterTest.cs @@ -369,6 +369,75 @@ public void TryConvertTo_NullableGuid__Invalid() Assert.Null(actual); } + [Theory] + [InlineData(1.1, "0.0#", "1.1")] // Single decimal place with optional second + [InlineData(1500, "0.00", "1500.00")] // Force two decimal places + [InlineData(1500, "0.##", "1500")] // Remove unnecessary decimals + [InlineData(0, "0.00", "0.00")] // Zero with fixed decimals + [InlineData(0, "0.##", "0")] // Zero with optional decimals + [InlineData(-1.1, "0.0#", "-1.1")] // Negative number with one decimal place + [InlineData(-1500, "0.00", "-1500.00")] // Negative number with two fixed decimals + [InlineData(1.999, "0.0", "2.0")] // Rounding up + [InlineData(1.111, "0.0", "1.1")] // Rounding down + [InlineData(1234567.89, "N2", "1,234,567.89")] // Large number with thousands separator + [InlineData(1234567.89, "#,##0.00", "1,234,567.89")] // Explicit thousands separator format + [InlineData(0.1234, "0.00%", "12.34%")] // Percentage formatting + [InlineData(0.12, "00.00", "00.12")] // Fixed zero's with fixed decimals + [InlineData(1234567.89, "0.00", "1234567.89")] // Fixed two decimals + public void FormatValue_Double_Format(double value, string format, string expected) + { + // Act + var actual = BindConverter.FormatValue(value, format, CultureInfo.InvariantCulture); + + // Assert + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(1.1, "0.0#", "1.1")] // Single decimal place with optional second + [InlineData(1500, "0.00", "1500.00")] // Force two decimal places + [InlineData(1500, "0.##", "1500")] // Remove unnecessary decimals + [InlineData(0, "0.00", "0.00")] // Zero with fixed decimals + [InlineData(0, "0.##", "0")] // Zero with optional decimals + [InlineData(-1.1, "0.0#", "-1.1")] // Negative number with one decimal place + [InlineData(-1500, "0.00", "-1500.00")] // Negative number with two fixed decimals + [InlineData(1.999, "0.0", "2.0")] // Rounding up + [InlineData(1.111, "0.0", "1.1")] // Rounding down + [InlineData(1234567.89, "N2", "1,234,567.89")] // Large number with thousands separator + [InlineData(1234567.89, "#,##0.00", "1,234,567.89")] // Explicit thousands separator format + [InlineData(0.1234, "0.00%", "12.34%")] // Percentage formatting + [InlineData(0.12, "00.00", "00.12")] // Fixed zero's with fixed decimals + public void FormatValue_Decimal_Format(decimal value, string format, string expected) + { + // Act + var actual = BindConverter.FormatValue(value, format, CultureInfo.InvariantCulture); + + // Assert + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(1.1, "0.0#", "1.1")] // Single decimal place with optional second + [InlineData(1500, "0.00", "1500.00")] // Force two decimal places + [InlineData(1500, "0.##", "1500")] // Remove unnecessary decimals + [InlineData(0, "0.00", "0.00")] // Zero with fixed decimals + [InlineData(0, "0.##", "0")] // Zero with optional decimals + [InlineData(-1.1, "0.0#", "-1.1")] // Negative number with one decimal place + [InlineData(-1500, "0.00", "-1500.00")] // Negative number with two fixed decimals + [InlineData(1.999, "0.0", "2.0")] // Rounding up + [InlineData(1.111, "0.0", "1.1")] // Rounding down + [InlineData(1234567.89, "N2", "1,234,567.88")] // Large number with thousands separator + [InlineData(0.1234, "0.00%", "12.34%")] // Percentage formatting + [InlineData(0.12, "00.00", "00.12")] // Fixed zero's with fixed decimals + public void FormatValue_Float_Format(float value, string format, string expected) + { + // Act + var actual = BindConverter.FormatValue(value, format, CultureInfo.InvariantCulture); + + // Assert + Assert.Equal(expected, actual); + } + private enum SomeLetters { A, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy