diff --git a/src/Controls/src/SourceGen/KnownMarkups.cs b/src/Controls/src/SourceGen/KnownMarkups.cs
index a706bcb34d60..6974f988ae2b 100644
--- a/src/Controls/src/SourceGen/KnownMarkups.cs
+++ b/src/Controls/src/SourceGen/KnownMarkups.cs
@@ -772,6 +772,13 @@ internal static bool ProvideValueForStaticResourceExtension(ElementNode node, In
return false;
}
+ if (variable is ILocalValue localVar && !localVar.Type.Equals(context.Compilation.GetTypeByMetadataName("System.String")!, SymbolEqualityComparer.Default))
+ {
+ returnType = localVar.Type;
+ value = localVar.ValueAccessor;
+ return true;
+ }
+
//if the resource is a string, try to convert it
if (resource.CollectionItems.Count == 1 && resource.CollectionItems[0] is ValueNode vn && vn.Value is string)
{
diff --git a/src/Controls/tests/SourceGen.UnitTests/StaticResourceInMarkup.cs b/src/Controls/tests/SourceGen.UnitTests/StaticResourceInMarkup.cs
new file mode 100644
index 000000000000..294ffa9101fb
--- /dev/null
+++ b/src/Controls/tests/SourceGen.UnitTests/StaticResourceInMarkup.cs
@@ -0,0 +1,190 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.IO;
+using System.Linq;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.Maui.Controls.SourceGen;
+using Xunit;
+
+using static Microsoft.Maui.Controls.Xaml.UnitTests.SourceGen.SourceGeneratorDriver;
+
+namespace Microsoft.Maui.Controls.SourceGen.UnitTests;
+
+public class StaticResourceInMarkup : SourceGenXamlInitializeComponentTestBase
+{
+
+ [Fact]
+ public void ColorResourceAsStaticResourceInMarkupExtension_ShouldNotProduceCS0030Error()
+ {
+ // Test reproducing issue #32836: Color resource defined in XAML should be treated as Color, not string
+ // when used with StaticResource inside a markup extension
+ //
+ // This test validates that nested StaticResource in markup extensions generates correct code
+
+ var xaml =
+"""
+
+
+
+ #00FF00
+
+
+
+
+""";
+
+ var code =
+"""
+using System;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui.Controls.Xaml;
+using Microsoft.Maui.Graphics;
+
+namespace TestApp
+{
+ public partial class TestPage : ContentPage
+ {
+ public TestPage()
+ {
+ InitializeComponent();
+ }
+ }
+
+ public class MyExtension : IMarkupExtension
+ {
+ public Color Source { get; set; }
+
+ public Color ProvideValue(IServiceProvider serviceProvider)
+ {
+ return Source;
+ }
+
+ object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
+ {
+ return (this as IMarkupExtension).ProvideValue(serviceProvider);
+ }
+ }
+}
+""";
+
+ var testXamlFilePath = Path.Combine(Environment.CurrentDirectory, "Test.xaml");
+ var expected =
+$$"""
+//------------------------------------------------------------------------------
+//
+// This code was generated by a .NET MAUI source generator.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+#nullable enable
+
+namespace TestApp;
+
+[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Maui.Controls.SourceGen, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null", "10.0.0.0")]
+public partial class TestPage
+{
+ private partial void InitializeComponent()
+ {
+ // Fallback to Runtime inflation if the page was updated by HotReload
+ static string? getPathForType(global::System.Type type)
+ {
+ var assembly = type.Assembly;
+ foreach (var xria in global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(assembly))
+ {
+ if (xria.Type == type)
+ return xria.Path;
+ }
+ return null;
+ }
+
+ var rlr = global::Microsoft.Maui.Controls.Internals.ResourceLoader.ResourceProvider2?.Invoke(new global::Microsoft.Maui.Controls.Internals.ResourceLoader.ResourceLoadingQuery
+ {
+ AssemblyName = typeof(global::TestApp.TestPage).Assembly.GetName(),
+ ResourcePath = getPathForType(typeof(global::TestApp.TestPage)),
+ Instance = this,
+ });
+
+ if (rlr?.ResourceContent != null)
+ {
+ this.InitializeComponentRuntime();
+ return;
+ }
+
+ var color = new global::Microsoft.Maui.Graphics.Color(0f, 1f, 0f, 1f) /* #00FF00 */;
+ global::Microsoft.Maui.VisualDiagnostics.RegisterSourceInfo(color!, new global::System.Uri(@"Test.xaml;assembly=SourceGeneratorDriver.Generated", global::System.UriKind.Relative), 8, 4);
+ var staticResourceExtension = new global::Microsoft.Maui.Controls.Xaml.StaticResourceExtension();
+ global::Microsoft.Maui.VisualDiagnostics.RegisterSourceInfo(staticResourceExtension!, new global::System.Uri(@"Test.xaml;assembly=SourceGeneratorDriver.Generated", global::System.UriKind.Relative), 11, 9);
+ var myExtension = new global::TestApp.MyExtension();
+ global::Microsoft.Maui.VisualDiagnostics.RegisterSourceInfo(myExtension!, new global::System.Uri(@"Test.xaml;assembly=SourceGeneratorDriver.Generated", global::System.UriKind.Relative), 11, 9);
+ var label = new global::Microsoft.Maui.Controls.Label();
+ global::Microsoft.Maui.VisualDiagnostics.RegisterSourceInfo(label!, new global::System.Uri(@"Test.xaml;assembly=SourceGeneratorDriver.Generated", global::System.UriKind.Relative), 11, 3);
+ var __root = this;
+ global::Microsoft.Maui.VisualDiagnostics.RegisterSourceInfo(__root!, new global::System.Uri(@"Test.xaml;assembly=SourceGeneratorDriver.Generated", global::System.UriKind.Relative), 2, 2);
+#if !_MAUIXAML_SG_NAMESCOPE_DISABLE
+ global::Microsoft.Maui.Controls.Internals.INameScope iNameScope = global::Microsoft.Maui.Controls.Internals.NameScope.GetNameScope(__root) ?? new global::Microsoft.Maui.Controls.Internals.NameScope();
+#endif
+#if !_MAUIXAML_SG_NAMESCOPE_DISABLE
+ global::Microsoft.Maui.Controls.Internals.NameScope.SetNameScope(__root, iNameScope);
+#endif
+#if !_MAUIXAML_SG_NAMESCOPE_DISABLE
+ label.transientNamescope = iNameScope;
+#endif
+ __root.Resources["MyColor"] = color;
+#line 11 "{{testXamlFilePath}}"
+ staticResourceExtension.Key = "MyColor";
+#line default
+ var color1 = color;
+ if (global::Microsoft.Maui.VisualDiagnostics.GetSourceInfo(color1!) == null)
+ global::Microsoft.Maui.VisualDiagnostics.RegisterSourceInfo(color1!, new global::System.Uri(@"Test.xaml;assembly=SourceGeneratorDriver.Generated", global::System.UriKind.Relative), 11, 9);
+#line 11 "{{testXamlFilePath}}"
+ myExtension.Source = (global::Microsoft.Maui.Graphics.Color)color1;
+#line default
+ var xamlServiceProvider = new global::Microsoft.Maui.Controls.Xaml.Internals.XamlServiceProvider(__root);
+ var iProvideValueTarget = new global::Microsoft.Maui.Controls.Xaml.Internals.SimpleValueTargetProvider(
+ new object?[] {label, __root},
+ global::Microsoft.Maui.Controls.Label.TextColorProperty,
+#if !_MAUIXAML_SG_NAMESCOPE_DISABLE
+ new [] { iNameScope },
+#else
+ null,
+#endif
+ __root);
+ xamlServiceProvider.Add(typeof(global::Microsoft.Maui.Controls.Xaml.IReferenceProvider), iProvideValueTarget);
+ xamlServiceProvider.Add(typeof(global::Microsoft.Maui.Controls.Xaml.IProvideValueTarget), iProvideValueTarget);
+ var xmlNamespaceResolver = new global::Microsoft.Maui.Controls.Xaml.Internals.XmlNamespaceResolver();
+ xmlNamespaceResolver.Add("__f__", "http://schemas.microsoft.com/dotnet/2021/maui");
+ xmlNamespaceResolver.Add("__g__", "http://schemas.microsoft.com/dotnet/maui/global");
+ xmlNamespaceResolver.Add("", "http://schemas.microsoft.com/dotnet/2021/maui");
+ xmlNamespaceResolver.Add("x", "http://schemas.microsoft.com/winfx/2009/xaml");
+ xmlNamespaceResolver.Add("local", "clr-namespace:TestApp");
+ xamlServiceProvider.Add(typeof(global::Microsoft.Maui.Controls.Xaml.IXamlTypeResolver), new global::Microsoft.Maui.Controls.Xaml.Internals.XamlTypeResolver(xmlNamespaceResolver, typeof(global::TestApp.TestPage).Assembly));
+ xamlServiceProvider.Add(typeof(global::Microsoft.Maui.Controls.Xaml.IXmlLineInfoProvider), new global::Microsoft.Maui.Controls.Xaml.Internals.XmlLineInfoProvider(new global::Microsoft.Maui.Controls.Xaml.XmlLineInfo(11, 9)));
+ var color2 = (global::Microsoft.Maui.Graphics.Color)((global::Microsoft.Maui.Controls.Xaml.IMarkupExtension)myExtension).ProvideValue(xamlServiceProvider);
+ if (global::Microsoft.Maui.VisualDiagnostics.GetSourceInfo(color2!) == null)
+ global::Microsoft.Maui.VisualDiagnostics.RegisterSourceInfo(color2!, new global::System.Uri(@"Test.xaml;assembly=SourceGeneratorDriver.Generated", global::System.UriKind.Relative), 11, 9);
+#line 11 "{{testXamlFilePath}}"
+ label.SetValue(global::Microsoft.Maui.Controls.Label.TextColorProperty, color2);
+#line default
+#line 11 "{{testXamlFilePath}}"
+ __root.SetValue(global::Microsoft.Maui.Controls.ContentPage.ContentProperty, label);
+#line default
+ }
+}
+
+""";
+
+ var (result, generated) = RunGenerator(xaml, code);
+ Assert.False(result.Diagnostics.Any());
+ Assert.Equal(expected, generated, ignoreLineEndingDifferences: true);
+
+ }
+
+
+}
diff --git a/src/Controls/tests/Xaml.UnitTests/Issues/Maui32837.xaml b/src/Controls/tests/Xaml.UnitTests/Issues/Maui32837.xaml
new file mode 100644
index 000000000000..fef318e6859f
--- /dev/null
+++ b/src/Controls/tests/Xaml.UnitTests/Issues/Maui32837.xaml
@@ -0,0 +1,22 @@
+
+
+
+ 16
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Controls/tests/Xaml.UnitTests/Issues/Maui32837.xaml.cs b/src/Controls/tests/Xaml.UnitTests/Issues/Maui32837.xaml.cs
new file mode 100644
index 000000000000..9a278e188061
--- /dev/null
+++ b/src/Controls/tests/Xaml.UnitTests/Issues/Maui32837.xaml.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Globalization;
+using Microsoft.Maui.ApplicationModel;
+using Microsoft.Maui.Controls.Core.UnitTests;
+using Microsoft.Maui.Controls.Shapes;
+using Microsoft.Maui.Dispatching;
+using Microsoft.Maui.UnitTests;
+using NUnit.Framework;
+
+namespace Microsoft.Maui.Controls.Xaml.UnitTests;
+
+public partial class Maui32837 : Application
+{
+ public Maui32837() => InitializeComponent();
+
+ class Test
+ {
+ [SetUp]
+ public void Setup()
+ {
+ Application.SetCurrentApplication(new MockApplication());
+ DispatcherProvider.SetCurrent(new DispatcherProviderStub());
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ AppInfo.SetCurrent(null);
+ Application.SetCurrentApplication(null);
+ }
+
+ [Test]
+ public void ConverterReceivesCorrectValueFromStaticResource([Values] XamlInflator inflator)
+ {
+ var app = new Maui32837(inflator);
+
+ // Get the converter from resources
+ var converter = app.Resources["IntToCornerRadiusConverter"] as Maui32837IntToCornerRadiusConverter;
+ Assert.IsNotNull(converter, "Converter should not be null");
+
+ // Get the RoundRectangle from resources
+ var roundRect = app.Resources["MyRoundRectangle"] as RoundRectangle;
+ Assert.IsNotNull(roundRect, "RoundRectangle should not be null");
+
+ // The binding should have been evaluated and converter should have been called
+ // Check that the converter was actually invoked by looking at the result
+ var cornerRadius = roundRect.CornerRadius;
+
+ // The converter should have converted the int value 16 to CornerRadius(16)
+ Assert.That(cornerRadius.TopLeft, Is.EqualTo(16.0),
+ $"TopLeft corner radius should be 16.0 for {inflator}, but was {cornerRadius.TopLeft}");
+ Assert.That(cornerRadius.TopRight, Is.EqualTo(16.0),
+ $"TopRight corner radius should be 16.0 for {inflator}, but was {cornerRadius.TopRight}");
+ Assert.That(cornerRadius.BottomLeft, Is.EqualTo(16.0),
+ $"BottomLeft corner radius should be 16.0 for {inflator}, but was {cornerRadius.BottomLeft}");
+ Assert.That(cornerRadius.BottomRight, Is.EqualTo(16.0),
+ $"BottomRight corner radius should be 16.0 for {inflator}, but was {cornerRadius.BottomRight}");
+ }
+ }
+}
+
+#nullable enable
+public class Maui32837IntToCornerRadiusConverter : IValueConverter
+{
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ if (value is int radius)
+ {
+ return new CornerRadius(radius);
+ }
+ return new CornerRadius(0);
+ }
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ if (value is CornerRadius cornerRadius)
+ {
+ return (int)cornerRadius.TopLeft;
+ }
+ return 0;
+ }
+}