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,