diff --git a/src/Controls/src/SourceGen/TypeConverters/ThicknessConverter.cs b/src/Controls/src/SourceGen/TypeConverters/ThicknessConverter.cs
index c4573604e484..e08d445b120d 100644
--- a/src/Controls/src/SourceGen/TypeConverters/ThicknessConverter.cs
+++ b/src/Controls/src/SourceGen/TypeConverters/ThicknessConverter.cs
@@ -26,31 +26,31 @@ public string Convert(string value, BaseNode node, ITypeSymbol toType, IndentedT
switch (thickness.Length)
{
case 2:
- if (double.TryParse(thickness[0], NumberStyles.Number, CultureInfo.InvariantCulture, out double h)
- && double.TryParse(thickness[1], NumberStyles.Number, CultureInfo.InvariantCulture, out double v))
+ if (TryParseDouble(thickness[0], out double h)
+ && TryParseDouble(thickness[1], out double v))
{
var thicknessType = context.Compilation.GetTypeByMetadataName("Microsoft.Maui.Thickness")!;
- return $"new {thicknessType.ToFQDisplayString()}({FormatInvariant(h)}, {FormatInvariant(v)})";
+ return $"new {thicknessType.ToFQDisplayString()}({FormatDouble(h)}, {FormatDouble(v)})";
}
break;
case 4:
- if (double.TryParse(thickness[0], NumberStyles.Number, CultureInfo.InvariantCulture, out double l)
- && double.TryParse(thickness[1], NumberStyles.Number, CultureInfo.InvariantCulture, out double t)
- && double.TryParse(thickness[2], NumberStyles.Number, CultureInfo.InvariantCulture, out double r)
- && double.TryParse(thickness[3], NumberStyles.Number, CultureInfo.InvariantCulture, out double b))
+ if (TryParseDouble(thickness[0], out double l)
+ && TryParseDouble(thickness[1], out double t)
+ && TryParseDouble(thickness[2], out double r)
+ && TryParseDouble(thickness[3], out double b))
{
var thicknessType = context.Compilation.GetTypeByMetadataName("Microsoft.Maui.Thickness")!;
- return $"new {thicknessType.ToFQDisplayString()}({FormatInvariant(l)}, {FormatInvariant(t)}, {FormatInvariant(r)}, {FormatInvariant(b)})";
+ return $"new {thicknessType.ToFQDisplayString()}({FormatDouble(l)}, {FormatDouble(t)}, {FormatDouble(r)}, {FormatDouble(b)})";
}
break;
}
}
else
{ //single uniform thickness
- if (double.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out double l))
+ if (TryParseDouble(value, out double l))
{
var thicknessType = context.Compilation.GetTypeByMetadataName("Microsoft.Maui.Thickness")!;
- return $"new {thicknessType.ToFQDisplayString()}({FormatInvariant(l)})";
+ return $"new {thicknessType.ToFQDisplayString()}({FormatDouble(l)})";
}
}
}
@@ -58,4 +58,47 @@ public string Convert(string value, BaseNode node, ITypeSymbol toType, IndentedT
context.ReportConversionFailed(xmlLineInfo, value, Descriptors.ThicknessConversionFailed);
return "default";
}
+
+ ///
+ /// Tries to parse a double value, including special values like NaN, Infinity, -Infinity.
+ ///
+ static bool TryParseDouble(string value, out double result)
+ {
+ value = value.Trim();
+
+ // Handle special values that NumberStyles.Number doesn't parse
+ if (value.Equals("NaN", System.StringComparison.OrdinalIgnoreCase))
+ {
+ result = double.NaN;
+ return true;
+ }
+ if (value.Equals("Infinity", System.StringComparison.OrdinalIgnoreCase) ||
+ value.Equals("+Infinity", System.StringComparison.OrdinalIgnoreCase))
+ {
+ result = double.PositiveInfinity;
+ return true;
+ }
+ if (value.Equals("-Infinity", System.StringComparison.OrdinalIgnoreCase))
+ {
+ result = double.NegativeInfinity;
+ return true;
+ }
+
+ return double.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out result);
+ }
+
+ ///
+ /// Formats a double value for C# code generation, handling special values.
+ ///
+ static string FormatDouble(double value)
+ {
+ if (double.IsNaN(value))
+ return "double.NaN";
+ if (double.IsPositiveInfinity(value))
+ return "double.PositiveInfinity";
+ if (double.IsNegativeInfinity(value))
+ return "double.NegativeInfinity";
+
+ return FormatInvariant(value);
+ }
}
\ No newline at end of file
diff --git a/src/Controls/tests/Xaml.UnitTests/Issues/Maui33871.xaml b/src/Controls/tests/Xaml.UnitTests/Issues/Maui33871.xaml
new file mode 100644
index 000000000000..d35afb65953c
--- /dev/null
+++ b/src/Controls/tests/Xaml.UnitTests/Issues/Maui33871.xaml
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/src/Controls/tests/Xaml.UnitTests/Issues/Maui33871.xaml.cs b/src/Controls/tests/Xaml.UnitTests/Issues/Maui33871.xaml.cs
new file mode 100644
index 000000000000..c01e8d90b78a
--- /dev/null
+++ b/src/Controls/tests/Xaml.UnitTests/Issues/Maui33871.xaml.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+using Xunit;
+
+namespace Microsoft.Maui.Controls.Xaml.UnitTests;
+
+public partial class Maui33871 : ContentPage
+{
+ public Maui33871() => InitializeComponent();
+
+ [Collection("Issue")]
+ public class Tests
+ {
+ [Theory]
+ [XamlInflatorData]
+ internal void ThicknessConverterHandlesNaN(XamlInflator inflator)
+ {
+ // This test reproduces issue #33871:
+ // XSG fails to parse Padding="NaN" which creates a Thickness with all NaN values.
+ // This is used by Button to indicate "use platform default padding".
+ var page = new Maui33871(inflator);
+
+ Assert.NotNull(page);
+ Assert.NotNull(page.nanButton);
+
+ // Verify the padding was parsed correctly as NaN
+ Assert.True(page.nanButton.Padding.IsNaN);
+ }
+ }
+}