From fe2b8c0655dca444345832aca2e589339049cfc8 Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 13:26:34 +0100 Subject: [PATCH 01/18] Format : Float --- src/Components/Components/src/BindConverter.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index 06a03a05f390..a59d49f4b800 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -212,10 +212,15 @@ 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, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatFloatValueCore(value, culture, format); - private static string FormatFloatValueCore(float value, CultureInfo? culture) + 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); } @@ -228,15 +233,20 @@ 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, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatNullableFloatValueCore(value, culture, format); - private static string? FormatNullableFloatValueCore(float? value, CultureInfo? culture) + private static string? FormatNullableFloatValueCore(float? value, CultureInfo? culture, string? format) { if (value == null) { return null; } + if (format != null) + { + return value.ToString(format, culture ?? CultureInfo.CurrentCulture); + } + return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); } From 2d8d18ec8cf7806a1235c0281d7843137011797a Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 13:26:49 +0100 Subject: [PATCH 02/18] Format : Double --- src/Components/Components/src/BindConverter.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index a59d49f4b800..fdbd4c710398 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -259,10 +259,15 @@ private static string FormatFloatValueCore(float value, CultureInfo? culture, st /// /// 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, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatDoubleValueCore(value, culture, format); - private static string FormatDoubleValueCore(double value, CultureInfo? culture) + 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); } @@ -275,15 +280,20 @@ 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, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatNullableDoubleValueCore(value, culture, format); - private static string? FormatNullableDoubleValueCore(double? value, CultureInfo? culture) + private static string? FormatNullableDoubleValueCore(double? value, CultureInfo? culture, string? format) { if (value == null) { return null; } + if (format != null) + { + return value.ToString(format, culture ?? CultureInfo.CurrentCulture); + } + return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); } From 92630e3b682b6b3b5d6ca386e275a66ae94cbc38 Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 13:27:00 +0100 Subject: [PATCH 03/18] Format : Decimal --- .../Components/src/BindConverter.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index fdbd4c710398..7ef279f6bae0 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -306,10 +306,15 @@ 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, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatDecimalValueCore(value, culture, format); - private static string FormatDecimalValueCore(decimal value, CultureInfo? culture) + 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); } @@ -319,18 +324,24 @@ private static string FormatDecimalValueCore(decimal value, CultureInfo? culture /// The value to format. /// /// The to use while formatting. Defaults to . + /// The to use while formatting. /// /// 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, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatNullableDecimalValueCore(value, culture, format); - private static string? FormatNullableDecimalValueCore(decimal? value, CultureInfo? culture) + private static string? FormatNullableDecimalValueCore(decimal? value, CultureInfo? culture, string? format) { if (value == null) { return null; } + if (format != null) + { + return value.ToString(format, culture ?? CultureInfo.CurrentCulture); + } + return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); } From c170699ef778362f1c1ac7eb896efe9e856ab21d Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 13:33:36 +0100 Subject: [PATCH 04/18] Documentation of additional format param. --- src/Components/Components/src/BindConverter.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index 7ef279f6bae0..a8ec10919e3c 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -210,6 +210,7 @@ private static string FormatShortValueCore(short value, CultureInfo? culture) /// /// 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, CultureInfo? culture = null, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatFloatValueCore(value, culture, format); @@ -231,6 +232,7 @@ private static string FormatFloatValueCore(float value, CultureInfo? culture, st /// /// 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, CultureInfo? culture = null, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatNullableFloatValueCore(value, culture, format); @@ -257,6 +259,7 @@ private static string FormatFloatValueCore(float value, CultureInfo? culture, st /// /// 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, CultureInfo? culture = null, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatDoubleValueCore(value, culture, format); @@ -278,6 +281,7 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture, /// /// 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, CultureInfo? culture = null, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatNullableDoubleValueCore(value, culture, format); @@ -304,6 +308,7 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture, /// /// 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, CultureInfo? culture = null, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatDecimalValueCore(value, culture, format); @@ -326,6 +331,7 @@ private static string FormatDecimalValueCore(decimal value, CultureInfo? culture /// The to use while formatting. Defaults to . /// The to use while formatting. /// + /// 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, CultureInfo? culture = null, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatNullableDecimalValueCore(value, culture, format); From 7fc2e4451eece300ede99892bf95545f3cacd90a Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 13:43:38 +0100 Subject: [PATCH 05/18] InputNumber - Add parameter `Format` --- src/Components/Web/src/Forms/InputNumber.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Components/Web/src/Forms/InputNumber.cs b/src/Components/Web/src/Forms/InputNumber.cs index b346b4b39772..3ada22ec19f8 100644 --- a/src/Components/Web/src/Forms/InputNumber.cs +++ b/src/Components/Web/src/Forms/InputNumber.cs @@ -40,6 +40,11 @@ private static string GetStepAttributeValue() /// [Parameter] public string ParsingErrorMessage { get; set; } = "The {0} field must be a number."; + /// + /// Gets or sets the format to be used when displaying a number of types: | | . + /// + [Parameter] public string? Format { get; set; } + /// /// Gets or sets the associated . /// @@ -102,13 +107,13 @@ protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(fa return BindConverter.FormatValue(@short, CultureInfo.InvariantCulture); case float @float: - return BindConverter.FormatValue(@float, CultureInfo.InvariantCulture); + return BindConverter.FormatValue(@float, CultureInfo.InvariantCulture, Format); case double @double: - return BindConverter.FormatValue(@double, CultureInfo.InvariantCulture); + return BindConverter.FormatValue(@double, CultureInfo.InvariantCulture, Format); case decimal @decimal: - return BindConverter.FormatValue(@decimal, CultureInfo.InvariantCulture); + return BindConverter.FormatValue(@decimal, CultureInfo.InvariantCulture, Format); default: throw new InvalidOperationException($"Unsupported type {value.GetType()}"); From a3e55daa41d0c10c2db37c7597338f6a87b0832a Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 13:46:03 +0100 Subject: [PATCH 06/18] Fix Docs --- src/Components/Components/src/BindConverter.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index a8ec10919e3c..1cc6373cfbff 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -329,7 +329,6 @@ private static string FormatDecimalValueCore(decimal value, CultureInfo? culture /// The value to format. /// /// The to use while formatting. Defaults to . - /// The to use while formatting. /// /// The format to use. Provided to . /// The formatted value. From 4fa6842f4bbc3cd308b3a1cbf7c66536415b6474 Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 13:52:35 +0100 Subject: [PATCH 07/18] Fix nullable Value --- src/Components/Components/src/BindConverter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index 1cc6373cfbff..6c453d9cd82d 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -246,7 +246,7 @@ private static string FormatFloatValueCore(float value, CultureInfo? culture, st if (format != null) { - return value.ToString(format, culture ?? CultureInfo.CurrentCulture); + return value.Value.ToString(format, culture ?? CultureInfo.CurrentCulture); } return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); @@ -295,7 +295,7 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture, if (format != null) { - return value.ToString(format, culture ?? CultureInfo.CurrentCulture); + return value.Value.ToString(format, culture ?? CultureInfo.CurrentCulture); } return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); @@ -344,7 +344,7 @@ private static string FormatDecimalValueCore(decimal value, CultureInfo? culture if (format != null) { - return value.ToString(format, culture ?? CultureInfo.CurrentCulture); + return value.Value.ToString(format, culture ?? CultureInfo.CurrentCulture); } return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); From a66bcda5f9b2e61c14f30f252e48d326d294f2aa Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 13:53:28 +0100 Subject: [PATCH 08/18] Binders --- src/Components/Components/src/BindConverter.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index 6c453d9cd82d..42a23c1848ba 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -1005,7 +1005,9 @@ 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) { @@ -1082,7 +1084,9 @@ 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) { @@ -1159,7 +1163,9 @@ 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) { From 9f12296b4712c21e038db50895df84751d2e4560 Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 14:11:32 +0100 Subject: [PATCH 09/18] BinderConverter - BindParserWithFormat --- .../Components/src/BindConverter.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index 42a23c1848ba..66ae5b9c9ea8 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -1009,6 +1009,11 @@ public static bool TryConvertToNullableFloat(object? obj, CultureInfo? culture, 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, out float value) { var text = (string?)obj; @@ -1035,6 +1040,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)) @@ -1089,6 +1099,11 @@ public static bool TryConvertToNullableDouble(object? obj, CultureInfo? culture, 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)) @@ -1114,6 +1129,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)) @@ -1168,6 +1188,11 @@ public static bool TryConvertToNullableDecimal(object? obj, CultureInfo? culture 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)) @@ -1187,6 +1212,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)) From f3607509225f9fdd17ba4334d33d5d0b08765ff1 Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 14:35:47 +0100 Subject: [PATCH 10/18] Complete Bind-Converter --- .../Components/src/BindConverter.cs | 114 +++++++++++++++++- 1 file changed, 112 insertions(+), 2 deletions(-) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index 66ae5b9c9ea8..65148b0921c0 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -24,7 +24,6 @@ public static class BindConverter private static readonly object BoxedFalse = false; private delegate object? BindFormatter(T value, CultureInfo? culture); - internal delegate bool BindParser(object? obj, CultureInfo? culture, [MaybeNullWhen(false)] out T value); internal delegate bool BindParserWithFormat(object? obj, CultureInfo? culture, string? format, [MaybeNullWhen(false)] out T value); @@ -203,6 +202,17 @@ private static string FormatShortValueCore(short value, CultureInfo? culture) return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); } + /// + /// Formats the provided for inclusion in an attribute. + /// + /// The value to format. + /// + /// The to use while formatting. Defaults 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, CultureInfo? culture = null) => FormatFloatValueCore(value, culture, format: null); + /// /// Formats the provided for inclusion in an attribute. /// @@ -225,6 +235,22 @@ private static string FormatFloatValueCore(float value, CultureInfo? culture, st return value.ToString(culture ?? CultureInfo.CurrentCulture); } + private static string FormatFloatValueCore(float value, CultureInfo? culture) + { + return value.ToString(culture ?? CultureInfo.CurrentCulture); + } + + /// + /// Formats the provided for inclusion in an attribute. + /// + /// The value to format. + /// + /// The to use while formatting. Defaults 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, CultureInfo? culture = null) => FormatNullableFloatValueCore(value, culture, format: null); + /// /// Formats the provided for inclusion in an attribute. /// @@ -252,6 +278,27 @@ private static string FormatFloatValueCore(float value, CultureInfo? culture, st return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); } + private static string? FormatNullableFloatValueCore(float? value, CultureInfo? culture) + { + if (value == null) + { + return null; + } + + return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); + } + + /// + /// Formats the provided for inclusion in an attribute. + /// + /// The value to format. + /// + /// The to use while formatting. Defaults 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, CultureInfo? culture = null) => FormatDoubleValueCore(value, culture, format: null); + /// /// Formats the provided for inclusion in an attribute. /// @@ -274,6 +321,22 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture, return value.ToString(culture ?? CultureInfo.CurrentCulture); } + private static string FormatDoubleValueCore(double value, CultureInfo? culture) + { + return value.ToString(culture ?? CultureInfo.CurrentCulture); + } + + /// + /// Formats the provided for inclusion in an attribute. + /// + /// The value to format. + /// + /// The to use while formatting. Defaults 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, CultureInfo? culture = null) => FormatNullableDoubleValueCore(value, culture, format: null); + /// /// Formats the provided for inclusion in an attribute. /// @@ -286,6 +349,16 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture, [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, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatNullableDoubleValueCore(value, culture, format); + private static string? FormatNullableDoubleValueCore(double? value, CultureInfo? culture) + { + if (value == null) + { + return null; + } + + return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); + } + private static string? FormatNullableDoubleValueCore(double? value, CultureInfo? culture, string? format) { if (value == null) @@ -301,6 +374,17 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture, return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); } + /// + /// Formats the provided for inclusion in an attribute. + /// + /// The value to format. + /// + /// The to use while formatting. Defaults 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, CultureInfo? culture = null) => FormatDecimalValueCore(value, culture, format: null); + /// /// Formats the provided for inclusion in an attribute. /// @@ -313,6 +397,11 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture, [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, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = 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) @@ -323,6 +412,17 @@ private static string FormatDecimalValueCore(decimal value, CultureInfo? culture return value.ToString(culture ?? CultureInfo.CurrentCulture); } + /// + /// Formats the provided as a . + /// + /// The value to format. + /// + /// The to use while formatting. Defaults 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, CultureInfo? culture = null) => FormatNullableDecimalValueCore(value, culture, format: null); + /// /// Formats the provided as a . /// @@ -335,6 +435,16 @@ private static string FormatDecimalValueCore(decimal value, CultureInfo? culture [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, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatNullableDecimalValueCore(value, culture, format); + private static string? FormatNullableDecimalValueCore(decimal? value, CultureInfo? culture) + { + if (value == null) + { + return null; + } + + return value.Value.ToString(culture ?? CultureInfo.CurrentCulture); + } + private static string? FormatNullableDecimalValueCore(decimal? value, CultureInfo? culture, string? format) { if (value == null) @@ -1014,7 +1124,7 @@ private static bool ConvertToFloatCore(object? obj, CultureInfo? culture, out fl return ConvertToFloatCore(obj, culture, format: null, out value); } - private static bool ConvertToFloatCore(object? obj, CultureInfo? culture, out float value) + private static bool ConvertToFloatCore(object? obj, CultureInfo? culture, string? format, out float value) { var text = (string?)obj; if (string.IsNullOrEmpty(text)) From da86c9f34ce60957e108e7b3df8f9815acaab65c Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 15:39:02 +0100 Subject: [PATCH 11/18] Realign format --- src/Components/Components/src/BindConverter.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index 65148b0921c0..c769b1c1737d 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -223,7 +223,7 @@ private static string FormatShortValueCore(short value, CultureInfo? culture) /// 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, CultureInfo? culture = null, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatFloatValueCore(value, culture, format); + 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) { @@ -261,7 +261,7 @@ private static string FormatFloatValueCore(float value, CultureInfo? culture) /// 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, CultureInfo? culture = null, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatNullableFloatValueCore(value, culture, format); + 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) { @@ -309,7 +309,7 @@ private static string FormatFloatValueCore(float value, CultureInfo? culture) /// 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, CultureInfo? culture = null, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatDoubleValueCore(value, culture, format); + 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) { @@ -347,7 +347,7 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture) /// 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, CultureInfo? culture = null, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatNullableDoubleValueCore(value, culture, format); + 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) { @@ -395,7 +395,7 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture) /// 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, CultureInfo? culture = null, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatDecimalValueCore(value, culture, format); + 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) { @@ -433,7 +433,7 @@ private static string FormatDecimalValueCore(decimal value, CultureInfo? culture /// 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, CultureInfo? culture = null, [StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format = null) => FormatNullableDecimalValueCore(value, culture, format); + 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) { From f06678ea6698154685c3dfaa2e19942490f5de8a Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 16:15:18 +0100 Subject: [PATCH 12/18] Add API Docs --- src/Components/Components/src/PublicAPI.Unshipped.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Components/Components/src/PublicAPI.Unshipped.txt b/src/Components/Components/src/PublicAPI.Unshipped.txt index 07e51aca6bd3..f7446dbbb024 100644 --- a/src/Components/Components/src/PublicAPI.Unshipped.txt +++ b/src/Components/Components/src/PublicAPI.Unshipped.txt @@ -14,6 +14,12 @@ 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.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! From 9879935b815b7e968c9183d311406cb3e148655e Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 16:15:25 +0100 Subject: [PATCH 13/18] Add BindConverter Tests --- .../Components/test/BindConverterTest.cs | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) 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, From a2204d9186e13fe3578d82571c8c0a7c57f6a877 Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 16:24:58 +0100 Subject: [PATCH 14/18] Nullable format --- src/Components/Components/src/BindConverter.cs | 14 +++++++------- .../Components/src/PublicAPI.Unshipped.txt | 13 +++++++------ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index c769b1c1737d..05aa9185d467 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -223,7 +223,7 @@ private static string FormatShortValueCore(short value, CultureInfo? culture) /// 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); + 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) { @@ -261,7 +261,7 @@ private static string FormatFloatValueCore(float value, CultureInfo? culture) /// 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); + 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) { @@ -309,7 +309,7 @@ private static string FormatFloatValueCore(float value, CultureInfo? culture) /// 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); + 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) { @@ -347,7 +347,7 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture) /// 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); + 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) { @@ -395,7 +395,7 @@ private static string FormatDoubleValueCore(double value, CultureInfo? culture) /// 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); + 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) { @@ -433,7 +433,7 @@ private static string FormatDecimalValueCore(decimal value, CultureInfo? culture /// 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); + 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) { @@ -481,7 +481,7 @@ 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(DateTime value, [StringSyntax(StringSyntaxAttribute.DateTimeFormat)] string format, CultureInfo? culture = null) => FormatDateTimeValueCore(value, format, culture); + public static string FormatValue(DateTime value, [StringSyntax(StringSyntaxAttribute.DateTimeFormat)] string? format, CultureInfo? culture = null) => FormatDateTimeValueCore(value, format, culture); private static string FormatDateTimeValueCore(DateTime value, string? format, CultureInfo? culture) { diff --git a/src/Components/Components/src/PublicAPI.Unshipped.txt b/src/Components/Components/src/PublicAPI.Unshipped.txt index f7446dbbb024..cf74c70d9515 100644 --- a/src/Components/Components/src/PublicAPI.Unshipped.txt +++ b/src/Components/Components/src/PublicAPI.Unshipped.txt @@ -14,12 +14,13 @@ 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.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.BindConverter.FormatValue(System.DateTime value, string? format, System.Globalization.CultureInfo? culture = null) -> string! 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! From bf5a1dc3061ac0e9bd251f7e0032667be98c73b0 Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 16:25:09 +0100 Subject: [PATCH 15/18] InputNumber --- src/Components/Web/src/Forms/InputNumber.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Components/Web/src/Forms/InputNumber.cs b/src/Components/Web/src/Forms/InputNumber.cs index 3ada22ec19f8..9f894a45dc3d 100644 --- a/src/Components/Web/src/Forms/InputNumber.cs +++ b/src/Components/Web/src/Forms/InputNumber.cs @@ -107,13 +107,13 @@ protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(fa return BindConverter.FormatValue(@short, CultureInfo.InvariantCulture); case float @float: - return BindConverter.FormatValue(@float, CultureInfo.InvariantCulture, Format); + return BindConverter.FormatValue(@float, Format, CultureInfo.InvariantCulture); case double @double: - return BindConverter.FormatValue(@double, CultureInfo.InvariantCulture, Format); + return BindConverter.FormatValue(@double, Format, CultureInfo.InvariantCulture); case decimal @decimal: - return BindConverter.FormatValue(@decimal, CultureInfo.InvariantCulture, Format); + return BindConverter.FormatValue(@decimal, Format, CultureInfo.InvariantCulture); default: throw new InvalidOperationException($"Unsupported type {value.GetType()}"); From 9cc2a835e4ffcfcf168c284b678720d517399e09 Mon Sep 17 00:00:00 2001 From: Benjamin Vertonghen Date: Thu, 30 Jan 2025 17:20:51 +0100 Subject: [PATCH 16/18] Tests for input --- .../Components/src/BindConverter.cs | 2 +- .../Components/src/PublicAPI.Unshipped.txt | 1 - src/Components/Web/src/Forms/InputNumber.cs | 2 +- .../Web/src/PublicAPI.Unshipped.txt | 4 +- .../Web/test/Forms/InputNumberTest.cs | 76 +++++++++++++++---- 5 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index 05aa9185d467..5b83b2cb1017 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -481,7 +481,7 @@ 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(DateTime value, [StringSyntax(StringSyntaxAttribute.DateTimeFormat)] string? format, CultureInfo? culture = null) => FormatDateTimeValueCore(value, format, culture); + public static string FormatValue(DateTime value, [StringSyntax(StringSyntaxAttribute.DateTimeFormat)] string format, CultureInfo? culture = null) => FormatDateTimeValueCore(value, format, culture); private static string FormatDateTimeValueCore(DateTime value, string? format, CultureInfo? culture) { diff --git a/src/Components/Components/src/PublicAPI.Unshipped.txt b/src/Components/Components/src/PublicAPI.Unshipped.txt index cf74c70d9515..97035ee4501a 100644 --- a/src/Components/Components/src/PublicAPI.Unshipped.txt +++ b/src/Components/Components/src/PublicAPI.Unshipped.txt @@ -20,7 +20,6 @@ static Microsoft.AspNetCore.Components.BindConverter.FormatValue(double value, s 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.BindConverter.FormatValue(System.DateTime value, string? format, System.Globalization.CultureInfo? culture = null) -> string! 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/Web/src/Forms/InputNumber.cs b/src/Components/Web/src/Forms/InputNumber.cs index 9f894a45dc3d..194b7fdc078e 100644 --- a/src/Components/Web/src/Forms/InputNumber.cs +++ b/src/Components/Web/src/Forms/InputNumber.cs @@ -41,7 +41,7 @@ private static string GetStepAttributeValue() [Parameter] public string ParsingErrorMessage { get; set; } = "The {0} field must be a number."; /// - /// Gets or sets the format to be used when displaying a number of types: | | . + /// Gets or sets the format to be used when displaying a number of types: , , . /// [Parameter] public string? Format { get; set; } diff --git a/src/Components/Web/src/PublicAPI.Unshipped.txt b/src/Components/Web/src/PublicAPI.Unshipped.txt index 99365e10804e..4bcac3bcdd25 100644 --- a/src/Components/Web/src/PublicAPI.Unshipped.txt +++ b/src/Components/Web/src/PublicAPI.Unshipped.txt @@ -1,3 +1,5 @@ #nullable enable Microsoft.AspNetCore.Components.Web.Internal.IInternalWebJSInProcessRuntime.InvokeJS(in Microsoft.JSInterop.Infrastructure.JSInvocationInfo invocationInfo) -> string! -virtual Microsoft.AspNetCore.Components.Routing.NavLink.ShouldMatch(string! uriAbsolute) -> bool \ No newline at end of file +virtual Microsoft.AspNetCore.Components.Routing.NavLink.ShouldMatch(string! uriAbsolute) -> bool +Microsoft.AspNetCore.Components.Forms.InputNumber.Format.get -> string? +Microsoft.AspNetCore.Components.Forms.InputNumber.Format.set -> void diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index 12a7891b4bb4..ebdf9509482a 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -20,21 +20,59 @@ public InputNumberTest() _testRenderer = new TestRenderer(services.BuildServiceProvider()); } + [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.0000", "1500.0000")] // Force four 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 async Task FormatDoubles(string value, string format, string expected) + { + // Arrange + var model = new TestModel(); + var rootComponent = new TestInputHostComponent> + { + EditContext = new EditContext(model), + ValueExpression = () => model.Double, + AdditionalAttributes = new Dictionary + { + { "Format", format } + } + }; + var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent); + + // Act + inputComponent.CurrentValueAsString = value; + + // Assert + Assert.Equal(expected, inputComponent.CurrentValueAsString); + } + [Fact] public async Task ValidationErrorUsesDisplayAttributeName() { // Arrange var model = new TestModel(); - var rootComponent = new TestInputHostComponent + var rootComponent = new TestInputHostComponent> { EditContext = new EditContext(model), - ValueExpression = () => model.SomeNumber, + ValueExpression = () => model.Int, AdditionalAttributes = new Dictionary - { - { "DisplayName", "Some number" } - } + { + { "DisplayName", "Some number" } + } }; - var fieldIdentifier = FieldIdentifier.Create(() => model.SomeNumber); + var fieldIdentifier = FieldIdentifier.Create(() => model.Int); var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent); // Act @@ -51,10 +89,10 @@ public async Task InputElementIsAssignedSuccessfully() { // Arrange var model = new TestModel(); - var rootComponent = new TestInputHostComponent + var rootComponent = new TestInputHostComponent> { EditContext = new EditContext(model), - ValueExpression = () => model.SomeNumber, + ValueExpression = () => model.Int, }; // Act @@ -69,10 +107,10 @@ public async Task UserDefinedTypeAttributeOverridesDefault() { // Arrange var model = new TestModel(); - var hostComponent = new TestInputHostComponent + var hostComponent = new TestInputHostComponent> { EditContext = new EditContext(model), - ValueExpression = () => model.SomeNumber, + ValueExpression = () => model.Int, AdditionalAttributes = new Dictionary { { "type", "range" } // User-defined 'type' attribute to override default @@ -93,21 +131,31 @@ public async Task UserDefinedTypeAttributeOverridesDefault() Assert.Equal("range", typeAttributeFrame.AttributeValue); } - private async Task RenderAndGetTestInputNumberComponentIdAsync(TestInputHostComponent hostComponent) + private async Task RenderAndGetTestInputNumberComponentIdAsync(TestInputHostComponent> hostComponent) { var hostComponentId = _testRenderer.AssignRootComponentId(hostComponent); await _testRenderer.RenderRootComponentAsync(hostComponentId); var batch = _testRenderer.Batches.Single(); - return batch.GetComponentFrames().Single().ComponentId; + return batch.GetComponentFrames>().Single().ComponentId; } private class TestModel { - public int SomeNumber { get; set; } + public int Int { get; set; } + public double Double { get; set; } + public float Float { get; set; } + public decimal Decimal { get; set; } } - private class TestInputNumberComponent : InputNumber + class TestInputNumberComponent : InputNumber { + public new TValue CurrentValue => base.CurrentValue; + + public new string CurrentValueAsString + { + get => base.CurrentValueAsString; + set => base.CurrentValueAsString = value; + } public async Task SetCurrentValueAsStringAsync(string value) { // This is equivalent to the subclass writing to CurrentValueAsString From 3b5745a5d2d37875546bd580a4ba1b737e47bdc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Rozto=C4=8Dil?= Date: Tue, 17 Jun 2025 15:28:34 +0200 Subject: [PATCH 17/18] Remove InputNumber changes --- .../Components/src/BindConverter.cs | 1 + src/Components/Web/src/Forms/InputNumber.cs | 11 +-- .../Web/src/PublicAPI.Unshipped.txt | 4 +- .../Web/test/Forms/InputNumberTest.cs | 76 ++++--------------- 4 files changed, 19 insertions(+), 73 deletions(-) diff --git a/src/Components/Components/src/BindConverter.cs b/src/Components/Components/src/BindConverter.cs index 5b83b2cb1017..2cae3af98440 100644 --- a/src/Components/Components/src/BindConverter.cs +++ b/src/Components/Components/src/BindConverter.cs @@ -24,6 +24,7 @@ public static class BindConverter private static readonly object BoxedFalse = false; private delegate object? BindFormatter(T value, CultureInfo? culture); + internal delegate bool BindParser(object? obj, CultureInfo? culture, [MaybeNullWhen(false)] out T value); internal delegate bool BindParserWithFormat(object? obj, CultureInfo? culture, string? format, [MaybeNullWhen(false)] out T value); diff --git a/src/Components/Web/src/Forms/InputNumber.cs b/src/Components/Web/src/Forms/InputNumber.cs index 194b7fdc078e..b346b4b39772 100644 --- a/src/Components/Web/src/Forms/InputNumber.cs +++ b/src/Components/Web/src/Forms/InputNumber.cs @@ -40,11 +40,6 @@ private static string GetStepAttributeValue() /// [Parameter] public string ParsingErrorMessage { get; set; } = "The {0} field must be a number."; - /// - /// Gets or sets the format to be used when displaying a number of types: , , . - /// - [Parameter] public string? Format { get; set; } - /// /// Gets or sets the associated . /// @@ -107,13 +102,13 @@ protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(fa return BindConverter.FormatValue(@short, CultureInfo.InvariantCulture); case float @float: - return BindConverter.FormatValue(@float, Format, CultureInfo.InvariantCulture); + return BindConverter.FormatValue(@float, CultureInfo.InvariantCulture); case double @double: - return BindConverter.FormatValue(@double, Format, CultureInfo.InvariantCulture); + return BindConverter.FormatValue(@double, CultureInfo.InvariantCulture); case decimal @decimal: - return BindConverter.FormatValue(@decimal, Format, CultureInfo.InvariantCulture); + return BindConverter.FormatValue(@decimal, CultureInfo.InvariantCulture); default: throw new InvalidOperationException($"Unsupported type {value.GetType()}"); diff --git a/src/Components/Web/src/PublicAPI.Unshipped.txt b/src/Components/Web/src/PublicAPI.Unshipped.txt index 4bcac3bcdd25..99365e10804e 100644 --- a/src/Components/Web/src/PublicAPI.Unshipped.txt +++ b/src/Components/Web/src/PublicAPI.Unshipped.txt @@ -1,5 +1,3 @@ #nullable enable Microsoft.AspNetCore.Components.Web.Internal.IInternalWebJSInProcessRuntime.InvokeJS(in Microsoft.JSInterop.Infrastructure.JSInvocationInfo invocationInfo) -> string! -virtual Microsoft.AspNetCore.Components.Routing.NavLink.ShouldMatch(string! uriAbsolute) -> bool -Microsoft.AspNetCore.Components.Forms.InputNumber.Format.get -> string? -Microsoft.AspNetCore.Components.Forms.InputNumber.Format.set -> void +virtual Microsoft.AspNetCore.Components.Routing.NavLink.ShouldMatch(string! uriAbsolute) -> bool \ No newline at end of file diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index ebdf9509482a..12a7891b4bb4 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -20,59 +20,21 @@ public InputNumberTest() _testRenderer = new TestRenderer(services.BuildServiceProvider()); } - [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.0000", "1500.0000")] // Force four 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 async Task FormatDoubles(string value, string format, string expected) - { - // Arrange - var model = new TestModel(); - var rootComponent = new TestInputHostComponent> - { - EditContext = new EditContext(model), - ValueExpression = () => model.Double, - AdditionalAttributes = new Dictionary - { - { "Format", format } - } - }; - var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent); - - // Act - inputComponent.CurrentValueAsString = value; - - // Assert - Assert.Equal(expected, inputComponent.CurrentValueAsString); - } - [Fact] public async Task ValidationErrorUsesDisplayAttributeName() { // Arrange var model = new TestModel(); - var rootComponent = new TestInputHostComponent> + var rootComponent = new TestInputHostComponent { EditContext = new EditContext(model), - ValueExpression = () => model.Int, + ValueExpression = () => model.SomeNumber, AdditionalAttributes = new Dictionary - { - { "DisplayName", "Some number" } - } + { + { "DisplayName", "Some number" } + } }; - var fieldIdentifier = FieldIdentifier.Create(() => model.Int); + var fieldIdentifier = FieldIdentifier.Create(() => model.SomeNumber); var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent); // Act @@ -89,10 +51,10 @@ public async Task InputElementIsAssignedSuccessfully() { // Arrange var model = new TestModel(); - var rootComponent = new TestInputHostComponent> + var rootComponent = new TestInputHostComponent { EditContext = new EditContext(model), - ValueExpression = () => model.Int, + ValueExpression = () => model.SomeNumber, }; // Act @@ -107,10 +69,10 @@ public async Task UserDefinedTypeAttributeOverridesDefault() { // Arrange var model = new TestModel(); - var hostComponent = new TestInputHostComponent> + var hostComponent = new TestInputHostComponent { EditContext = new EditContext(model), - ValueExpression = () => model.Int, + ValueExpression = () => model.SomeNumber, AdditionalAttributes = new Dictionary { { "type", "range" } // User-defined 'type' attribute to override default @@ -131,31 +93,21 @@ public async Task UserDefinedTypeAttributeOverridesDefault() Assert.Equal("range", typeAttributeFrame.AttributeValue); } - private async Task RenderAndGetTestInputNumberComponentIdAsync(TestInputHostComponent> hostComponent) + private async Task RenderAndGetTestInputNumberComponentIdAsync(TestInputHostComponent hostComponent) { var hostComponentId = _testRenderer.AssignRootComponentId(hostComponent); await _testRenderer.RenderRootComponentAsync(hostComponentId); var batch = _testRenderer.Batches.Single(); - return batch.GetComponentFrames>().Single().ComponentId; + return batch.GetComponentFrames().Single().ComponentId; } private class TestModel { - public int Int { get; set; } - public double Double { get; set; } - public float Float { get; set; } - public decimal Decimal { get; set; } + public int SomeNumber { get; set; } } - class TestInputNumberComponent : InputNumber + private class TestInputNumberComponent : InputNumber { - public new TValue CurrentValue => base.CurrentValue; - - public new string CurrentValueAsString - { - get => base.CurrentValueAsString; - set => base.CurrentValueAsString = value; - } public async Task SetCurrentValueAsStringAsync(string value) { // This is equivalent to the subclass writing to CurrentValueAsString From fa4b34f6a734ce678aa50b7ad257766df785961d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Rozto=C4=8Dil?= Date: Tue, 17 Jun 2025 17:06:12 +0200 Subject: [PATCH 18/18] Add CreateBinder overloads with format for float, double and decimal --- .../EventCallbackFactoryBinderExtensions.cs | 132 ++++++++++++++++++ .../Components/src/PublicAPI.Unshipped.txt | 6 + 2 files changed, 138 insertions(+) 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 97035ee4501a..86029676506f 100644 --- a/src/Components/Components/src/PublicAPI.Unshipped.txt +++ b/src/Components/Components/src/PublicAPI.Unshipped.txt @@ -20,6 +20,12 @@ static Microsoft.AspNetCore.Components.BindConverter.FormatValue(double value, s 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!