Fix RelativeSource Binding is NULL with XAML SourceGen and IsAotCompatible in iOS Release Mode - #35798
Conversation
W1: Add IXamlDataTypeProviderWithBindingNodeInfo internal interface to avoid
concrete cast to XamlDataTypeProvider in BindingExtension. Any future
IXamlDataTypeProvider implementation can opt in by implementing the
extended internal interface.
W2: Update HasRelativeSource in SetPropertiesVisitor to also check
XmlName(null, "Source") — mirrors the defensive check already in
KnownMarkups.HasExplicitBindingSource.
Also scope the guard to RelativeSource only (not x:Reference), fixing
a regression in Maui23711 where x:Reference with inherited x:DataType
should still compile TypedBinding.
W3: Add Scenario C test — {RelativeSource Self} inside a DataTemplate with
inherited x:DataType must not inherit the item type. Before fix, the
item type caused IsAssignableFrom(Label)=false, nulling the Self source.
Three new test variants (Runtime/SourceGen/XamlC) cover this regression.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35798Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35798" |
|
Hey there @@KarthikRajaKalaimani! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
|
/review -b feature/enhanced-reviewer -p ios |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 1 findings
See inline comments for details.
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the ai's suggestions?
MauiBot
left a comment
There was a problem hiding this comment.
AI Review Summary
@KarthikRajaKalaimani — new AI review results are available based on this last commit:
47003bf.
updated To request a fresh review after new comments or commits, comment/review rerun.
Review Sessions — click to expand
Gate — Test Before & After Fix
Gate Result: ✅ PASSED
Platform: IOS · Base: main · Merge base: e904e900
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
📄 Maui35564 Maui35564 |
✅ FAIL — 22s | ✅ PASS — 22s |
🔴 Without fix — 📄 Maui35564: FAIL ✅ · 22s
(truncated to last 15,000 chars)
ing XC0045: Binding: Property "BindingContext" not found on "Microsoft.Maui.Controls.Xaml.UnitTests.Maui33291Item". [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui33293.xaml(14,29): XamlC warning XC0045: Binding: Property "BindingContext" not found on "Microsoft.Maui.Controls.Xaml.UnitTests.Maui33293Product". [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui33876.xaml(8,20): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui34490.xaml(12,25): XamlC warning XC0045: Binding: Property "BindingContext" not found on "Microsoft.Maui.Controls.Xaml.UnitTests.Maui34490ItemModel". [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui35564.xaml(18,33): XamlC warning XC0045: Binding: Property "ItemTappedCommand" not found on "Microsoft.Maui.Controls.Xaml.UnitTests.Maui35564Item". [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui35564.xaml(55,32): XamlC warning XC0045: Binding: Property "AutomationId" not found on "Microsoft.Maui.Controls.Xaml.UnitTests.Maui35564Item". [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui6367.xaml(10,50): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui8149.xaml(12,43): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/RefToXamlControl.xaml(7,33): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/SetValue.xaml(20,26): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/SetValue.xaml(52,27): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/SetValue.xaml(53,27): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/WarnOnObsolete.xaml(6,25): XamlC warning XC0618: Property, Property setter or BindableProperty "ObsoleteBP" is deprecated. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/WarnOnObsolete.xaml(6,42): XamlC warning XC0618: Property, Property setter or BindableProperty "ObsoleteProp" is deprecated. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/WarnOnObsolete.xaml(6,61): XamlC warning XC0618: Property, Property setter or BindableProperty "ObsoletePropSetter" is deprecated. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/XReference.xaml(16,4): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/XReference.xaml(21,26): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/XReference.xaml(21,77): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Gh2007.rtxc.xaml(3,9): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
Controls.Xaml.UnitTests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.10] Discovering: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.29] Discovered: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.30] Starting: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.41] RelativeSourceSelfInsideDataTemplateWithInheritedXDataType(inflator: Runtime) [FAIL]
[xUnit.net 00:00:02.41] Assert.Equal() Failure: Strings differ
[xUnit.net 00:00:02.41] Expected: "scenario-c"
[xUnit.net 00:00:02.41] Actual: null
[xUnit.net 00:00:02.41] Stack Trace:
[xUnit.net 00:00:02.41] /_/src/Controls/tests/Xaml.UnitTests/Issues/Maui35564.xaml.cs(176,0): at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35564.Tests.RelativeSourceSelfInsideDataTemplateWithInheritedXDataType(XamlInflator inflator)
[xUnit.net 00:00:02.41] at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
[xUnit.net 00:00:02.41] at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
[xUnit.net 00:00:02.42] RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(inflator: Runtime) [FAIL]
[xUnit.net 00:00:02.42] Assert.NotNull() Failure: Value is null
[xUnit.net 00:00:02.42] Stack Trace:
[xUnit.net 00:00:02.42] /_/src/Controls/tests/Xaml.UnitTests/Issues/Maui35564.xaml.cs(87,0): at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35564.Tests.RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(XamlInflator inflator)
[xUnit.net 00:00:02.42] at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
[xUnit.net 00:00:02.42] at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
[xUnit.net 00:00:02.43] RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(inflator: SourceGen) [FAIL]
[xUnit.net 00:00:02.43] Assert.IsAssignableFrom() Failure: Value is an incompatible type
[xUnit.net 00:00:02.43] Expected: typeof(Microsoft.Maui.Controls.Internals.TypedBindingBase)
[xUnit.net 00:00:02.43] Actual: typeof(Microsoft.Maui.Controls.Binding)
[xUnit.net 00:00:02.43] Stack Trace:
[xUnit.net 00:00:02.43] /_/src/Controls/tests/Xaml.UnitTests/Issues/Maui35564.xaml.cs(93,0): at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35564.Tests.RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(XamlInflator inflator)
[xUnit.net 00:00:02.43] at InvokeStub_Tests.RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(Object, Span`1)
[xUnit.net 00:00:02.43] at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
[xUnit.net 00:00:02.44] RelativeSourceCommandWithExplicitXDataTypeCompilesTypedBinding(inflator: SourceGen) [FAIL]
[xUnit.net 00:00:02.44] Assert.IsAssignableFrom() Failure: Value is an incompatible type
[xUnit.net 00:00:02.44] Expected: typeof(Microsoft.Maui.Controls.Internals.TypedBindingBase)
[xUnit.net 00:00:02.44] Actual: typeof(Microsoft.Maui.Controls.Binding)
[xUnit.net 00:00:02.44] Stack Trace:
[xUnit.net 00:00:02.44] /_/src/Controls/tests/Xaml.UnitTests/Issues/Maui35564.xaml.cs(140,0): at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35564.Tests.RelativeSourceCommandWithExplicitXDataTypeCompilesTypedBinding(XamlInflator inflator)
[xUnit.net 00:00:02.44] at InvokeStub_Tests.RelativeSourceCommandWithExplicitXDataTypeCompilesTypedBinding(Object, Span`1)
[xUnit.net 00:00:02.44] at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
Failed RelativeSourceSelfInsideDataTemplateWithInheritedXDataType(inflator: Runtime) [68 ms]
Error Message:
Assert.Equal() Failure: Strings differ
Expected: "scenario-c"
Actual: null
Stack Trace:
at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35564.Tests.RelativeSourceSelfInsideDataTemplateWithInheritedXDataType(XamlInflator inflator) in /_/src/Controls/tests/Xaml.UnitTests/Issues/Maui35564.xaml.cs:line 176
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
Passed RelativeSourceSelfInsideDataTemplateWithInheritedXDataType(inflator: SourceGen) [4 ms]
Passed RelativeSourceSelfInsideDataTemplateWithInheritedXDataType(inflator: XamlC) [1 ms]
Failed RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(inflator: Runtime) [7 ms]
Error Message:
Assert.NotNull() Failure: Value is null
Stack Trace:
at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35564.Tests.RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(XamlInflator inflator) in /_/src/Controls/tests/Xaml.UnitTests/Issues/Maui35564.xaml.cs:line 87
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
Failed RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(inflator: SourceGen) [2 ms]
Error Message:
Assert.IsAssignableFrom() Failure: Value is an incompatible type
Expected: typeof(Microsoft.Maui.Controls.Internals.TypedBindingBase)
Actual: typeof(Microsoft.Maui.Controls.Binding)
Stack Trace:
at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35564.Tests.RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(XamlInflator inflator) in /_/src/Controls/tests/Xaml.UnitTests/Issues/Maui35564.xaml.cs:line 93
at InvokeStub_Tests.RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(Object, Span`1)
at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
Passed RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(inflator: XamlC) [< 1 ms]
Passed RelativeSourceCommandWithExplicitXDataTypeCompilesTypedBinding(inflator: Runtime) [8 ms]
Passed RelativeSourceCommandWithExplicitXDataTypeCompilesTypedBinding(inflator: XamlC) [1 ms]
Failed RelativeSourceCommandWithExplicitXDataTypeCompilesTypedBinding(inflator: SourceGen) [< 1 ms]
Error Message:
Assert.IsAssignableFrom() Failure: Value is an incompatible type
Expected: typeof(Microsoft.Maui.Controls.Internals.TypedBindingBase)
Actual: typeof(Microsoft.Maui.Controls.Binding)
Stack Trace:
at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35564.Tests.RelativeSourceCommandWithExplicitXDataTypeCompilesTypedBinding(XamlInflator inflator) in /_/src/Controls/tests/Xaml.UnitTests/Issues/Maui35564.xaml.cs:line 140
at InvokeStub_Tests.RelativeSourceCommandWithExplicitXDataTypeCompilesTypedBinding(Object, Span`1)
at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
[xUnit.net 00:00:02.45] Finished: Microsoft.Maui.Controls.Xaml.UnitTests
Passed RelativeSourceSelfWithExplicitXDataTypeStaysUncompiled(inflator: SourceGen) [< 1 ms]
Passed RelativeSourceSelfWithExplicitXDataTypeStaysUncompiled(inflator: Runtime) [3 ms]
Passed RelativeSourceSelfWithExplicitXDataTypeStaysUncompiled(inflator: XamlC) [< 1 ms]
Test Run Failed.
Total tests: 12
Passed: 8
Failed: 4
Total time: 2.7100 Seconds
🟢 With fix — 📄 Maui35564: PASS ✅ · 22s
(truncated to last 15,000 chars)
c/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui13872.xaml(7,25): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui13872.xaml(8,25): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui17484.xaml(10,17): XamlC warning XC0618: Property, Property setter or BindableProperty "Name" is deprecated. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui18123.xaml(18,22): XamlC warning XC0023: Binding could be compiled to improve runtime performance if x:DataType is not explicitly null. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui18123.xaml(19,22): XamlC warning XC0023: Binding could be compiled to improve runtime performance if x:DataType is not explicitly null. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui18123.xaml(43,22): XamlC warning XC0023: Binding could be compiled to improve runtime performance if x:DataType is not explicitly null. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui18123.xaml(44,22): XamlC warning XC0023: Binding could be compiled to improve runtime performance if x:DataType is not explicitly null. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui20508.xaml(8,34): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui20768.xaml(6,32): XamlC warning XC0045: Binding: Property "Title" not found on "Microsoft.Maui.Controls.Xaml.UnitTests.ViewModel20768". [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui22877.xaml(6,28): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui23989.xaml(12,13): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui24472.xaml(41,32): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui24500.xaml(6,28): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui25309.xaml(21,9): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui25871.xaml(14,24): XamlC warning XC0045: Binding: Property "UpdateProgress" not found on "Microsoft.Maui.Controls.Xaml.UnitTests.Maui25871ViewModel". [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui25935.xaml(8,13): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui31939.xaml(7,29): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui31939.xaml(14,29): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui31939.xaml(15,29): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui31995.xaml(12,56): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui31995.xaml(30,56): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui31995.xaml(44,28): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui32056.xaml(9,9): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui32837.xaml(13,18): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Maui6367.xaml(10,50): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/RefToXamlControl.xaml(7,33): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/SetValue.xaml(20,26): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/SetValue.xaml(52,27): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/SetValue.xaml(53,27): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/WarnOnObsolete.xaml(6,25): XamlC warning XC0618: Property, Property setter or BindableProperty "ObsoleteBP" is deprecated. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/WarnOnObsolete.xaml(6,42): XamlC warning XC0618: Property, Property setter or BindableProperty "ObsoleteProp" is deprecated. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/WarnOnObsolete.xaml(6,61): XamlC warning XC0618: Property, Property setter or BindableProperty "ObsoletePropSetter" is deprecated. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/XReference.xaml(16,4): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
Controls.Xaml.UnitTests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.10] Discovering: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.72] Discovered: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.72] Starting: Microsoft.Maui.Controls.Xaml.UnitTests
Passed RelativeSourceSelfInsideDataTemplateWithInheritedXDataType(inflator: Runtime) [76 ms]
Passed RelativeSourceSelfInsideDataTemplateWithInheritedXDataType(inflator: SourceGen) [2 ms]
Passed RelativeSourceSelfInsideDataTemplateWithInheritedXDataType(inflator: XamlC) [1 ms]
Passed RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(inflator: Runtime) [7 ms]
Passed RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(inflator: SourceGen) [2 ms]
Passed RelativeSourceCommandBindsToAncestorWithXamlCCompilationEnabled(inflator: XamlC) [< 1 ms]
Passed RelativeSourceCommandWithExplicitXDataTypeCompilesTypedBinding(inflator: Runtime) [3 ms]
Passed RelativeSourceCommandWithExplicitXDataTypeCompilesTypedBinding(inflator: XamlC) [< 1 ms]
Passed RelativeSourceCommandWithExplicitXDataTypeCompilesTypedBinding(inflator: SourceGen) [< 1 ms]
[xUnit.net 00:00:02.87] Finished: Microsoft.Maui.Controls.Xaml.UnitTests
Passed RelativeSourceSelfWithExplicitXDataTypeStaysUncompiled(inflator: SourceGen) [< 1 ms]
Passed RelativeSourceSelfWithExplicitXDataTypeStaysUncompiled(inflator: Runtime) [9 ms]
Passed RelativeSourceSelfWithExplicitXDataTypeStaysUncompiled(inflator: XamlC) [< 1 ms]
Test Run Successful.
Total tests: 12
Passed: 12
Total time: 3.1321 Seconds
📁 Fix files reverted (5 files)
eng/pipelines/ci-copilot.ymlsrc/Controls/src/Build.Tasks/SetPropertiesVisitor.cssrc/Controls/src/SourceGen/KnownMarkups.cssrc/Controls/src/Xaml/MarkupExtensions/BindingExtension.cssrc/Controls/src/Xaml/XamlServiceProvider.cs
UI Tests
Full UI test matrix will run (no specific categories detected from PR changes).
Regression Cross-Reference
🔍 Regression Cross-Reference
🔴 Revert risks detected — this PR removes 1 line(s) previously added by labeled bug-fix PRs.
| File | Fix PR | Fixed issue(s) | Risk | Reverted line |
|---|---|---|---|---|
src/Controls/src/SourceGen/KnownMarkups.cs |
#34501 | #34490 | 🔴 REVERT | if ( !hasExplicitSource |
Action required: Verify that issues #34490 do not re-regress before merging.
🧪 Regression Tests to Verify
These tests were added by the fix PRs being reverted. They must still pass:
| Fix PR | Type | Test | Filter |
|---|---|---|---|
| #34501 | UnitTest | BindingDiagnosticsTests | BindingDiagnosticsTests |
| #34501 | XamlUnitTest | Maui34490ViewModel | Maui34490ViewModel |
🧪 Regression Test Results
✅ PASSED — 5 passed, 0 failed, 0 skipped
| Fix PR | Test | Type | Result |
|---|---|---|---|
| #32916 | Maui13856Tests | UnitTest | ✅ PASSED |
| #32916 | Maui13856 | XamlUnitTest | ✅ PASSED |
| #34727 | Maui34726 | XamlUnitTest | ✅ PASSED |
| #34501 | BindingDiagnosticsTests | UnitTest | ✅ PASSED |
| #34501 | Maui34490ViewModel | XamlUnitTest | ✅ PASSED |
Pre-Flight — Context & Validation
Issue: #35564 - RelativeSource AncestorType binding inside typed DataTemplate fails under XamlC/SourceGen/AOT
PR: #35798 - Fix RelativeSource binding DataType handling for XAML compilation
Platforms Affected: iOS primary; XAML runtime, XamlC, SourceGen/AOT paths are cross-platform
Files Changed: 4 implementation, 2 test
Key Findings
- The PR changes runtime
BindingExtension, XamlCSetPropertiesVisitor, and SourceGenKnownMarkupsso explicit-source bindings do not inherit a DataTemplate itemx:DataTypeunless the binding has a binding-local type or can derive an ancestor source type. - The added
Maui35564tests coverRelativeSource AncestorTypewith inherited and explicit bindingx:DataType, plusRelativeSource Selfguards across Runtime, XamlC, and SourceGen inflators. - GitHub CLI authentication is unavailable in this environment, so PR/issue discussion and live CI status could not be fetched; local branch content and generated review artifacts were used instead.
Code Review Summary
Verdict: NEEDS_DISCUSSION
Confidence: medium
Errors: 0 | Warnings: 2 | Suggestions: 0
Key code review findings:
src/Controls/src/Xaml/MarkupExtensions/BindingExtension.cs:117 preserves DataType for RelativeBindingSource only when the provider implements internal IXamlDataTypeProviderWithBindingNodeInfo; public/custom IXamlDataTypeProvider implementations cannot indicate binding-local type metadata.-
Required CI was reported as failing/pending by the review sub-agent; this could not be independently refreshed because gh is unauthenticated.-
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35798 | Track whether is binding-local, suppress inherited DataType for runtime RelativeSource/Self, and compile AncestorType in XamlC/SourceGen | PASSED (Gate) | BindingExtension.cs, XamlServiceProvider.cs, SetPropertiesVisitor.cs, KnownMarkups.cs, Maui35564.xaml* |
Original PR |
Code Review — Deep Analysis
Code PR #35798Review
Independent Assessment
What this changes: This changes XAML binding compilation/runtime behavior so RelativeSource bindings inside typed templates stop inheriting template x:DataType unless it is declared on the binding itself, while allowing SourceGen/XamlC to compile RelativeSource AncestorType bindings using the ancestor type.
Inferred motivation: The change appears intended to fix AOT/trimmed iOS Release failures where SourceGen fell back to reflection for ancestor bindings and runtime/XamlC could apply the template item type to an explicit relative source.
Reconciliation with PR Narrative
Author claims: The PR says SourceGen + AOT can null RelativeSource AncestorType commands in CollectionView.ItemTemplate, and fixes this by distinguishing binding-local from inherited x:DataType, using ancestor type for typed binding generation, and adding Maui35564 XAML regression tests.
Agreement/disagreement: This matches the code: KnownMarkups and SetPropertiesVisitor now special-case RelativeSource AncestorType, BindingExtension suppresses inherited data type on explicit sources, and tests cover Runtime/XamlC/SourceGen variants. I have one compatibility question about public/custom IXamlDataTypeProvider callers.
Findings
Public IXamlDataTypeProvider callers lose RelativeSource DataTypeWarning ####
src/Controls/src/Xaml/MarkupExtensions/BindingExtension.cs:117 now preserves DataType for RelativeBindingSource only when the provider also implements the new internal IXamlDataTypeProviderWithBindingNodeInfo. Public/custom IXamlDataTypeProvider implementations (and new XamlDataTypeProvider(string)) cannot indicate that their data type is binding-local, so RelativeSource bindings that previously received Binding.DataType now silently get null. Is that intentional for public service-provider callers, or should the public string constructor/default provider state be treated as binding-local?
Required CI is currently failingWarning ####
Public GitHub check-runs for head 47003bfc34459bc2b06d51201fd3c04e06abc982 show the combined status is pending with failures in maui-pr, Windows Debug build, Samples integration tests, and Windows Helix unit tests. I did not determine whether these are PR-caused or infrastructure/pre-existing, but the code-review workflow should not report LGTM while required CI is red.
Devil's Advocate
The new internal provider marker is deliberately narrower than the public interface, which is what prevents inherited template item types from being applied to explicit sources. The compatibility concern may be acceptable if IXamlDataTypeProvider is considered implementation detail despite being public/editor-hidden. I did not find issues in the SourceGen/XamlC ancestor-type resolution paths after checking the full changed files and added tests.
Verdict: NEEDS_DISCUSSION
Confidence: medium
Summary: The core approach looks sound and targeted, and the tests exercise the reported Runtime/XamlC/SourceGen scenarios. Before merge, maintainers should decide whether the public IXamlDataTypeProvider compatibility change is intentional, and CI needs to be reconciled because required checks are currently failing.
Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix | Preserve RelativeSource DataType in BindingExtension and skip mismatches later in BindingExpression based on RelativeBindingSource semantics Tests Not selected | 2 files | Expert review found weakened explicit wrong-x:DataType diagnostics | passed / |
| 2 | try-fix | Use separate internal IXamlBindingDataTypeProvider service so built-in runtime can distinguish inherited vs binding-local x:DataType while public/custom IXamlDataTypeProvider keeps old behavior PASSED | 2 files | Selected; fixes code-review compatibility warning with lower API risk | |
| PR | PR #35798 | Extend public IXamlDataTypeProvider with internal marker interface and require that marker to preserve RelativeSource DataType PASSED (Gate) | 4 implementation files + tests | Original PR |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| maui-expert-reviewer | 1 | Yes | Suggested moving runtime decision into BindingExpression, adding a public versioned provider, using an internal metadata service, deriving DataType from AncestorType, or centralizing explicit-source resolution. |
| maui-expert-reviewer | 2 | Yes | Rejected candidate 1 because it weakens explicit wrong-x:DataType diagnostics; selected candidate 2 after adding a null service-provider guard. |
Exhausted: stopped because candidate #2 passed all runnable tests and was judged better than the PR fix.No
Selected Fix: Candidate # separate internal binding metadata service (IXamlBindingDataTypeProvider) instead of an internal extension of the public IXamlDataTypeProvider, preserving compatibility and diagnostics.2
Report — Final Recommendation
Comparative Report — PR #35798
Candidates Compared
| Rank | Candidate | Regression result | Assessment |
|---|---|---|---|
| 1 | pr-plus-reviewer |
PASSED | Best candidate. Keeps the PR's runtime/XamlC/SourceGen fix and applies the expert reviewer's compatibility improvement by using a separate internal binding metadata service. |
| 1 | try-fix-2 |
PASSED | Functionally equivalent to pr-plus-reviewer; selected during STEP 5a for the same reason. Ranked as equivalent but not chosen as the winner because the same fix is now represented as PR plus reviewer feedback. |
| 3 | pr |
PASSED | Correctly fixes #35564 and passes the gate/regression evidence, but leaves an actionable compatibility concern for public/custom IXamlDataTypeProvider implementations. |
| 4 | try-fix-1 |
PASSED | Passes recorded tests, but expert analysis found it weakens explicit wrong-x:DataType diagnostics for RelativeSource modes by moving suppression into BindingExpression. |
No candidate was recorded as failing regression tests. If any candidate had failed regression tests, it would be ranked below all passing candidates per review rules.
Winning Candidate
Winner: pr-plus-reviewer
pr-plus-reviewer is the safest complete fix: it preserves the raw PR's successful behavior for inherited x:DataType in typed DataTemplate RelativeSource AncestorType bindings, keeps explicit binding-local x:DataType validation, and avoids changing behavior for external/public IXamlDataTypeProvider consumers. try-fix-2 is equivalent, but the required Phase 1 reviewer feedback application makes pr-plus-reviewer the PR-fix-path winner.
Notes
- Gate result was already provided as passed; it was not rerun.
- Regression evidence from STEP 5a shows
Maui35564,Maui13856,Maui34726,BindingDiagnosticsTests, andMaui34490ViewModelcoverage passing where applicable. - Raw inline reviewer feedback was written to
CustomAgentLogsTmp/PRState/35798/PRAgent/inline-findings.json.
Future Action — review latest findings
No alternative fix was selected for this run. Review the session findings and CI results before merging.
…atible in iOS Release Mode (#35798) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details: When MauiXamlInflator=SourceGen + IsAotCompatible=true are set, a Command bound via {RelativeSource AncestorType} inside a CollectionView.ItemTemplate resolves to null at runtime on iOS Release (AOT) builds. ### Root Cause: The issue occurs when MauiXamlInflator=SourceGen and IsAotCompatible=true are set together on an iOS Release build. When a Command is bound using {RelativeSource AncestorType} inside a CollectionView.ItemTemplate, the binding resolves to null at runtime. The core problem is in the MAUI SourceGen (KnownMarkups.cs). When SourceGen processes a binding that has an explicit Source={RelativeSource AncestorType=...}, it sets hasExplicitSource=true. The existing guard if (!hasExplicitSource) then skips the TypedBinding code generation path entirely. This means SourceGen always falls back to generating a regular reflection-based Binding object for any RelativeSource binding — even when x:DataType is explicitly declared on the binding node, which would have given SourceGen all the type information it needs to generate a compiled TypedBinding. A regular Binding resolves its property path at runtime using .NET reflection (PropertyInfo.GetValue). This works perfectly fine in Debug mode because reflection metadata is fully available. However, on iOS Release builds, the AOT linker performs static analysis to trim unused code and metadata. Since the linker only sees a string like "ViewModel.ItemTappedCommand" inside the Binding object — and cannot trace that it will be used reflectively at runtime — it trims the property metadata. When the binding tries to resolve at runtime, the metadata is gone and the binding returns null. A secondary scenario exists for the Runtime inflator path: BindingExtension.ProvideValue was incorrectly propagating the inherited x:DataType from the parent DataTemplate (e.g., TestItem) onto the binding node itself. When IsXamlCBindingWithSourceCompilationEnabled=true, the runtime binding engine checks whether the source type (MainPage) is assignable from the DataType (TestItem) — which fails — so the source resolves to null and the Command becomes null. ### Description of Change: The fix introduces a way to distinguish between an x:DataType that was explicitly declared on the binding node versus one that was inherited from the enclosing DataTemplate. A new interface IXamlDataTypeProviderWithBindingNodeInfo with an IsDataTypeOnBindingNode property was added to XamlServiceProvider.cs to carry this information through the XAML processing pipeline. In KnownMarkups.cs, the SourceGen guard was updated from if (!hasExplicitSource) to if (!hasExplicitSource || xDataTypeOnBindingNode). This allows TypedBinding code generation to proceed for RelativeSource bindings when x:DataType is explicitly present on the binding node — giving SourceGen the type information it needs to emit a compiled lambda like static (m) => m.ViewModel.ItemTappedCommand instead of a reflective string lookup. This compiled lambda is a direct code reference that the AOT linker can see and preserve, making it safe on iOS Release AOT builds. In BindingExtension.cs, the Runtime inflator was fixed to only propagate DataType when IsDataTypeOnBindingNode=true, preventing the inherited DataType from causing incorrect assignability checks during RelativeSource binding resolution. Similarly, SetPropertiesVisitor.cs was updated for the XamlC path to skip TypedBinding compilation when the DataType is only inherited and not explicitly declared on the binding node. **Tested the behavior in the following platforms:** - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Reference: N/A ### Issues Fixed: Fixes #35564 ### Screenshots | Before | After | |---------|--------| | <Video src="https://github.com/user-attachments/assets/d3fb2c34-ad51-4053-91af-0cccd3dfca0b" Width="300" Height="600"> | <Video src="https://github.com/user-attachments/assets/50b53482-b03e-4b52-997d-abae3b6e9a2a" Width="300" Height="600"> | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…atible in iOS Release Mode (#35798) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details: When MauiXamlInflator=SourceGen + IsAotCompatible=true are set, a Command bound via {RelativeSource AncestorType} inside a CollectionView.ItemTemplate resolves to null at runtime on iOS Release (AOT) builds. ### Root Cause: The issue occurs when MauiXamlInflator=SourceGen and IsAotCompatible=true are set together on an iOS Release build. When a Command is bound using {RelativeSource AncestorType} inside a CollectionView.ItemTemplate, the binding resolves to null at runtime. The core problem is in the MAUI SourceGen (KnownMarkups.cs). When SourceGen processes a binding that has an explicit Source={RelativeSource AncestorType=...}, it sets hasExplicitSource=true. The existing guard if (!hasExplicitSource) then skips the TypedBinding code generation path entirely. This means SourceGen always falls back to generating a regular reflection-based Binding object for any RelativeSource binding — even when x:DataType is explicitly declared on the binding node, which would have given SourceGen all the type information it needs to generate a compiled TypedBinding. A regular Binding resolves its property path at runtime using .NET reflection (PropertyInfo.GetValue). This works perfectly fine in Debug mode because reflection metadata is fully available. However, on iOS Release builds, the AOT linker performs static analysis to trim unused code and metadata. Since the linker only sees a string like "ViewModel.ItemTappedCommand" inside the Binding object — and cannot trace that it will be used reflectively at runtime — it trims the property metadata. When the binding tries to resolve at runtime, the metadata is gone and the binding returns null. A secondary scenario exists for the Runtime inflator path: BindingExtension.ProvideValue was incorrectly propagating the inherited x:DataType from the parent DataTemplate (e.g., TestItem) onto the binding node itself. When IsXamlCBindingWithSourceCompilationEnabled=true, the runtime binding engine checks whether the source type (MainPage) is assignable from the DataType (TestItem) — which fails — so the source resolves to null and the Command becomes null. ### Description of Change: The fix introduces a way to distinguish between an x:DataType that was explicitly declared on the binding node versus one that was inherited from the enclosing DataTemplate. A new interface IXamlDataTypeProviderWithBindingNodeInfo with an IsDataTypeOnBindingNode property was added to XamlServiceProvider.cs to carry this information through the XAML processing pipeline. In KnownMarkups.cs, the SourceGen guard was updated from if (!hasExplicitSource) to if (!hasExplicitSource || xDataTypeOnBindingNode). This allows TypedBinding code generation to proceed for RelativeSource bindings when x:DataType is explicitly present on the binding node — giving SourceGen the type information it needs to emit a compiled lambda like static (m) => m.ViewModel.ItemTappedCommand instead of a reflective string lookup. This compiled lambda is a direct code reference that the AOT linker can see and preserve, making it safe on iOS Release AOT builds. In BindingExtension.cs, the Runtime inflator was fixed to only propagate DataType when IsDataTypeOnBindingNode=true, preventing the inherited DataType from causing incorrect assignability checks during RelativeSource binding resolution. Similarly, SetPropertiesVisitor.cs was updated for the XamlC path to skip TypedBinding compilation when the DataType is only inherited and not explicitly declared on the binding node. **Tested the behavior in the following platforms:** - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Reference: N/A ### Issues Fixed: Fixes #35564 ### Screenshots | Before | After | |---------|--------| | <Video src="https://github.com/user-attachments/assets/d3fb2c34-ad51-4053-91af-0cccd3dfca0b" Width="300" Height="600"> | <Video src="https://github.com/user-attachments/assets/50b53482-b03e-4b52-997d-abae3b6e9a2a" Width="300" Height="600"> | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…atible in iOS Release Mode (#35798) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details: When MauiXamlInflator=SourceGen + IsAotCompatible=true are set, a Command bound via {RelativeSource AncestorType} inside a CollectionView.ItemTemplate resolves to null at runtime on iOS Release (AOT) builds. ### Root Cause: The issue occurs when MauiXamlInflator=SourceGen and IsAotCompatible=true are set together on an iOS Release build. When a Command is bound using {RelativeSource AncestorType} inside a CollectionView.ItemTemplate, the binding resolves to null at runtime. The core problem is in the MAUI SourceGen (KnownMarkups.cs). When SourceGen processes a binding that has an explicit Source={RelativeSource AncestorType=...}, it sets hasExplicitSource=true. The existing guard if (!hasExplicitSource) then skips the TypedBinding code generation path entirely. This means SourceGen always falls back to generating a regular reflection-based Binding object for any RelativeSource binding — even when x:DataType is explicitly declared on the binding node, which would have given SourceGen all the type information it needs to generate a compiled TypedBinding. A regular Binding resolves its property path at runtime using .NET reflection (PropertyInfo.GetValue). This works perfectly fine in Debug mode because reflection metadata is fully available. However, on iOS Release builds, the AOT linker performs static analysis to trim unused code and metadata. Since the linker only sees a string like "ViewModel.ItemTappedCommand" inside the Binding object — and cannot trace that it will be used reflectively at runtime — it trims the property metadata. When the binding tries to resolve at runtime, the metadata is gone and the binding returns null. A secondary scenario exists for the Runtime inflator path: BindingExtension.ProvideValue was incorrectly propagating the inherited x:DataType from the parent DataTemplate (e.g., TestItem) onto the binding node itself. When IsXamlCBindingWithSourceCompilationEnabled=true, the runtime binding engine checks whether the source type (MainPage) is assignable from the DataType (TestItem) — which fails — so the source resolves to null and the Command becomes null. ### Description of Change: The fix introduces a way to distinguish between an x:DataType that was explicitly declared on the binding node versus one that was inherited from the enclosing DataTemplate. A new interface IXamlDataTypeProviderWithBindingNodeInfo with an IsDataTypeOnBindingNode property was added to XamlServiceProvider.cs to carry this information through the XAML processing pipeline. In KnownMarkups.cs, the SourceGen guard was updated from if (!hasExplicitSource) to if (!hasExplicitSource || xDataTypeOnBindingNode). This allows TypedBinding code generation to proceed for RelativeSource bindings when x:DataType is explicitly present on the binding node — giving SourceGen the type information it needs to emit a compiled lambda like static (m) => m.ViewModel.ItemTappedCommand instead of a reflective string lookup. This compiled lambda is a direct code reference that the AOT linker can see and preserve, making it safe on iOS Release AOT builds. In BindingExtension.cs, the Runtime inflator was fixed to only propagate DataType when IsDataTypeOnBindingNode=true, preventing the inherited DataType from causing incorrect assignability checks during RelativeSource binding resolution. Similarly, SetPropertiesVisitor.cs was updated for the XamlC path to skip TypedBinding compilation when the DataType is only inherited and not explicitly declared on the binding node. **Tested the behavior in the following platforms:** - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Reference: N/A ### Issues Fixed: Fixes #35564 ### Screenshots | Before | After | |---------|--------| | <Video src="https://github.com/user-attachments/assets/d3fb2c34-ad51-4053-91af-0cccd3dfca0b" Width="300" Height="600"> | <Video src="https://github.com/user-attachments/assets/50b53482-b03e-4b52-997d-abae3b6e9a2a" Width="300" Height="600"> | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…atible in iOS Release Mode (#35798) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details: When MauiXamlInflator=SourceGen + IsAotCompatible=true are set, a Command bound via {RelativeSource AncestorType} inside a CollectionView.ItemTemplate resolves to null at runtime on iOS Release (AOT) builds. ### Root Cause: The issue occurs when MauiXamlInflator=SourceGen and IsAotCompatible=true are set together on an iOS Release build. When a Command is bound using {RelativeSource AncestorType} inside a CollectionView.ItemTemplate, the binding resolves to null at runtime. The core problem is in the MAUI SourceGen (KnownMarkups.cs). When SourceGen processes a binding that has an explicit Source={RelativeSource AncestorType=...}, it sets hasExplicitSource=true. The existing guard if (!hasExplicitSource) then skips the TypedBinding code generation path entirely. This means SourceGen always falls back to generating a regular reflection-based Binding object for any RelativeSource binding — even when x:DataType is explicitly declared on the binding node, which would have given SourceGen all the type information it needs to generate a compiled TypedBinding. A regular Binding resolves its property path at runtime using .NET reflection (PropertyInfo.GetValue). This works perfectly fine in Debug mode because reflection metadata is fully available. However, on iOS Release builds, the AOT linker performs static analysis to trim unused code and metadata. Since the linker only sees a string like "ViewModel.ItemTappedCommand" inside the Binding object — and cannot trace that it will be used reflectively at runtime — it trims the property metadata. When the binding tries to resolve at runtime, the metadata is gone and the binding returns null. A secondary scenario exists for the Runtime inflator path: BindingExtension.ProvideValue was incorrectly propagating the inherited x:DataType from the parent DataTemplate (e.g., TestItem) onto the binding node itself. When IsXamlCBindingWithSourceCompilationEnabled=true, the runtime binding engine checks whether the source type (MainPage) is assignable from the DataType (TestItem) — which fails — so the source resolves to null and the Command becomes null. ### Description of Change: The fix introduces a way to distinguish between an x:DataType that was explicitly declared on the binding node versus one that was inherited from the enclosing DataTemplate. A new interface IXamlDataTypeProviderWithBindingNodeInfo with an IsDataTypeOnBindingNode property was added to XamlServiceProvider.cs to carry this information through the XAML processing pipeline. In KnownMarkups.cs, the SourceGen guard was updated from if (!hasExplicitSource) to if (!hasExplicitSource || xDataTypeOnBindingNode). This allows TypedBinding code generation to proceed for RelativeSource bindings when x:DataType is explicitly present on the binding node — giving SourceGen the type information it needs to emit a compiled lambda like static (m) => m.ViewModel.ItemTappedCommand instead of a reflective string lookup. This compiled lambda is a direct code reference that the AOT linker can see and preserve, making it safe on iOS Release AOT builds. In BindingExtension.cs, the Runtime inflator was fixed to only propagate DataType when IsDataTypeOnBindingNode=true, preventing the inherited DataType from causing incorrect assignability checks during RelativeSource binding resolution. Similarly, SetPropertiesVisitor.cs was updated for the XamlC path to skip TypedBinding compilation when the DataType is only inherited and not explicitly declared on the binding node. **Tested the behavior in the following platforms:** - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Reference: N/A ### Issues Fixed: Fixes #35564 ### Screenshots | Before | After | |---------|--------| | <Video src="https://github.com/user-attachments/assets/d3fb2c34-ad51-4053-91af-0cccd3dfca0b" Width="300" Height="600"> | <Video src="https://github.com/user-attachments/assets/50b53482-b03e-4b52-997d-abae3b6e9a2a" Width="300" Height="600"> | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…atible in iOS Release Mode (#35798) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details: When MauiXamlInflator=SourceGen + IsAotCompatible=true are set, a Command bound via {RelativeSource AncestorType} inside a CollectionView.ItemTemplate resolves to null at runtime on iOS Release (AOT) builds. ### Root Cause: The issue occurs when MauiXamlInflator=SourceGen and IsAotCompatible=true are set together on an iOS Release build. When a Command is bound using {RelativeSource AncestorType} inside a CollectionView.ItemTemplate, the binding resolves to null at runtime. The core problem is in the MAUI SourceGen (KnownMarkups.cs). When SourceGen processes a binding that has an explicit Source={RelativeSource AncestorType=...}, it sets hasExplicitSource=true. The existing guard if (!hasExplicitSource) then skips the TypedBinding code generation path entirely. This means SourceGen always falls back to generating a regular reflection-based Binding object for any RelativeSource binding — even when x:DataType is explicitly declared on the binding node, which would have given SourceGen all the type information it needs to generate a compiled TypedBinding. A regular Binding resolves its property path at runtime using .NET reflection (PropertyInfo.GetValue). This works perfectly fine in Debug mode because reflection metadata is fully available. However, on iOS Release builds, the AOT linker performs static analysis to trim unused code and metadata. Since the linker only sees a string like "ViewModel.ItemTappedCommand" inside the Binding object — and cannot trace that it will be used reflectively at runtime — it trims the property metadata. When the binding tries to resolve at runtime, the metadata is gone and the binding returns null. A secondary scenario exists for the Runtime inflator path: BindingExtension.ProvideValue was incorrectly propagating the inherited x:DataType from the parent DataTemplate (e.g., TestItem) onto the binding node itself. When IsXamlCBindingWithSourceCompilationEnabled=true, the runtime binding engine checks whether the source type (MainPage) is assignable from the DataType (TestItem) — which fails — so the source resolves to null and the Command becomes null. ### Description of Change: The fix introduces a way to distinguish between an x:DataType that was explicitly declared on the binding node versus one that was inherited from the enclosing DataTemplate. A new interface IXamlDataTypeProviderWithBindingNodeInfo with an IsDataTypeOnBindingNode property was added to XamlServiceProvider.cs to carry this information through the XAML processing pipeline. In KnownMarkups.cs, the SourceGen guard was updated from if (!hasExplicitSource) to if (!hasExplicitSource || xDataTypeOnBindingNode). This allows TypedBinding code generation to proceed for RelativeSource bindings when x:DataType is explicitly present on the binding node — giving SourceGen the type information it needs to emit a compiled lambda like static (m) => m.ViewModel.ItemTappedCommand instead of a reflective string lookup. This compiled lambda is a direct code reference that the AOT linker can see and preserve, making it safe on iOS Release AOT builds. In BindingExtension.cs, the Runtime inflator was fixed to only propagate DataType when IsDataTypeOnBindingNode=true, preventing the inherited DataType from causing incorrect assignability checks during RelativeSource binding resolution. Similarly, SetPropertiesVisitor.cs was updated for the XamlC path to skip TypedBinding compilation when the DataType is only inherited and not explicitly declared on the binding node. **Tested the behavior in the following platforms:** - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Reference: N/A ### Issues Fixed: Fixes #35564 ### Screenshots | Before | After | |---------|--------| | <Video src="https://github.com/user-attachments/assets/d3fb2c34-ad51-4053-91af-0cccd3dfca0b" Width="300" Height="600"> | <Video src="https://github.com/user-attachments/assets/50b53482-b03e-4b52-997d-abae3b6e9a2a" Width="300" Height="600"> | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…atible in iOS Release Mode (#35798) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details: When MauiXamlInflator=SourceGen + IsAotCompatible=true are set, a Command bound via {RelativeSource AncestorType} inside a CollectionView.ItemTemplate resolves to null at runtime on iOS Release (AOT) builds. ### Root Cause: The issue occurs when MauiXamlInflator=SourceGen and IsAotCompatible=true are set together on an iOS Release build. When a Command is bound using {RelativeSource AncestorType} inside a CollectionView.ItemTemplate, the binding resolves to null at runtime. The core problem is in the MAUI SourceGen (KnownMarkups.cs). When SourceGen processes a binding that has an explicit Source={RelativeSource AncestorType=...}, it sets hasExplicitSource=true. The existing guard if (!hasExplicitSource) then skips the TypedBinding code generation path entirely. This means SourceGen always falls back to generating a regular reflection-based Binding object for any RelativeSource binding — even when x:DataType is explicitly declared on the binding node, which would have given SourceGen all the type information it needs to generate a compiled TypedBinding. A regular Binding resolves its property path at runtime using .NET reflection (PropertyInfo.GetValue). This works perfectly fine in Debug mode because reflection metadata is fully available. However, on iOS Release builds, the AOT linker performs static analysis to trim unused code and metadata. Since the linker only sees a string like "ViewModel.ItemTappedCommand" inside the Binding object — and cannot trace that it will be used reflectively at runtime — it trims the property metadata. When the binding tries to resolve at runtime, the metadata is gone and the binding returns null. A secondary scenario exists for the Runtime inflator path: BindingExtension.ProvideValue was incorrectly propagating the inherited x:DataType from the parent DataTemplate (e.g., TestItem) onto the binding node itself. When IsXamlCBindingWithSourceCompilationEnabled=true, the runtime binding engine checks whether the source type (MainPage) is assignable from the DataType (TestItem) — which fails — so the source resolves to null and the Command becomes null. ### Description of Change: The fix introduces a way to distinguish between an x:DataType that was explicitly declared on the binding node versus one that was inherited from the enclosing DataTemplate. A new interface IXamlDataTypeProviderWithBindingNodeInfo with an IsDataTypeOnBindingNode property was added to XamlServiceProvider.cs to carry this information through the XAML processing pipeline. In KnownMarkups.cs, the SourceGen guard was updated from if (!hasExplicitSource) to if (!hasExplicitSource || xDataTypeOnBindingNode). This allows TypedBinding code generation to proceed for RelativeSource bindings when x:DataType is explicitly present on the binding node — giving SourceGen the type information it needs to emit a compiled lambda like static (m) => m.ViewModel.ItemTappedCommand instead of a reflective string lookup. This compiled lambda is a direct code reference that the AOT linker can see and preserve, making it safe on iOS Release AOT builds. In BindingExtension.cs, the Runtime inflator was fixed to only propagate DataType when IsDataTypeOnBindingNode=true, preventing the inherited DataType from causing incorrect assignability checks during RelativeSource binding resolution. Similarly, SetPropertiesVisitor.cs was updated for the XamlC path to skip TypedBinding compilation when the DataType is only inherited and not explicitly declared on the binding node. **Tested the behavior in the following platforms:** - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Reference: N/A ### Issues Fixed: Fixes #35564 ### Screenshots | Before | After | |---------|--------| | <Video src="https://github.com/user-attachments/assets/d3fb2c34-ad51-4053-91af-0cccd3dfca0b" Width="300" Height="600"> | <Video src="https://github.com/user-attachments/assets/50b53482-b03e-4b52-997d-abae3b6e9a2a" Width="300" Height="600"> | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…atible in iOS Release Mode (#35798) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details: When MauiXamlInflator=SourceGen + IsAotCompatible=true are set, a Command bound via {RelativeSource AncestorType} inside a CollectionView.ItemTemplate resolves to null at runtime on iOS Release (AOT) builds. ### Root Cause: The issue occurs when MauiXamlInflator=SourceGen and IsAotCompatible=true are set together on an iOS Release build. When a Command is bound using {RelativeSource AncestorType} inside a CollectionView.ItemTemplate, the binding resolves to null at runtime. The core problem is in the MAUI SourceGen (KnownMarkups.cs). When SourceGen processes a binding that has an explicit Source={RelativeSource AncestorType=...}, it sets hasExplicitSource=true. The existing guard if (!hasExplicitSource) then skips the TypedBinding code generation path entirely. This means SourceGen always falls back to generating a regular reflection-based Binding object for any RelativeSource binding — even when x:DataType is explicitly declared on the binding node, which would have given SourceGen all the type information it needs to generate a compiled TypedBinding. A regular Binding resolves its property path at runtime using .NET reflection (PropertyInfo.GetValue). This works perfectly fine in Debug mode because reflection metadata is fully available. However, on iOS Release builds, the AOT linker performs static analysis to trim unused code and metadata. Since the linker only sees a string like "ViewModel.ItemTappedCommand" inside the Binding object — and cannot trace that it will be used reflectively at runtime — it trims the property metadata. When the binding tries to resolve at runtime, the metadata is gone and the binding returns null. A secondary scenario exists for the Runtime inflator path: BindingExtension.ProvideValue was incorrectly propagating the inherited x:DataType from the parent DataTemplate (e.g., TestItem) onto the binding node itself. When IsXamlCBindingWithSourceCompilationEnabled=true, the runtime binding engine checks whether the source type (MainPage) is assignable from the DataType (TestItem) — which fails — so the source resolves to null and the Command becomes null. ### Description of Change: The fix introduces a way to distinguish between an x:DataType that was explicitly declared on the binding node versus one that was inherited from the enclosing DataTemplate. A new interface IXamlDataTypeProviderWithBindingNodeInfo with an IsDataTypeOnBindingNode property was added to XamlServiceProvider.cs to carry this information through the XAML processing pipeline. In KnownMarkups.cs, the SourceGen guard was updated from if (!hasExplicitSource) to if (!hasExplicitSource || xDataTypeOnBindingNode). This allows TypedBinding code generation to proceed for RelativeSource bindings when x:DataType is explicitly present on the binding node — giving SourceGen the type information it needs to emit a compiled lambda like static (m) => m.ViewModel.ItemTappedCommand instead of a reflective string lookup. This compiled lambda is a direct code reference that the AOT linker can see and preserve, making it safe on iOS Release AOT builds. In BindingExtension.cs, the Runtime inflator was fixed to only propagate DataType when IsDataTypeOnBindingNode=true, preventing the inherited DataType from causing incorrect assignability checks during RelativeSource binding resolution. Similarly, SetPropertiesVisitor.cs was updated for the XamlC path to skip TypedBinding compilation when the DataType is only inherited and not explicitly declared on the binding node. **Tested the behavior in the following platforms:** - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Reference: N/A ### Issues Fixed: Fixes #35564 ### Screenshots | Before | After | |---------|--------| | <Video src="https://github.com/user-attachments/assets/d3fb2c34-ad51-4053-91af-0cccd3dfca0b" Width="300" Height="600"> | <Video src="https://github.com/user-attachments/assets/50b53482-b03e-4b52-997d-abae3b6e9a2a" Width="300" Height="600"> | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…atible in iOS Release Mode (#35798) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details: When MauiXamlInflator=SourceGen + IsAotCompatible=true are set, a Command bound via {RelativeSource AncestorType} inside a CollectionView.ItemTemplate resolves to null at runtime on iOS Release (AOT) builds. ### Root Cause: The issue occurs when MauiXamlInflator=SourceGen and IsAotCompatible=true are set together on an iOS Release build. When a Command is bound using {RelativeSource AncestorType} inside a CollectionView.ItemTemplate, the binding resolves to null at runtime. The core problem is in the MAUI SourceGen (KnownMarkups.cs). When SourceGen processes a binding that has an explicit Source={RelativeSource AncestorType=...}, it sets hasExplicitSource=true. The existing guard if (!hasExplicitSource) then skips the TypedBinding code generation path entirely. This means SourceGen always falls back to generating a regular reflection-based Binding object for any RelativeSource binding — even when x:DataType is explicitly declared on the binding node, which would have given SourceGen all the type information it needs to generate a compiled TypedBinding. A regular Binding resolves its property path at runtime using .NET reflection (PropertyInfo.GetValue). This works perfectly fine in Debug mode because reflection metadata is fully available. However, on iOS Release builds, the AOT linker performs static analysis to trim unused code and metadata. Since the linker only sees a string like "ViewModel.ItemTappedCommand" inside the Binding object — and cannot trace that it will be used reflectively at runtime — it trims the property metadata. When the binding tries to resolve at runtime, the metadata is gone and the binding returns null. A secondary scenario exists for the Runtime inflator path: BindingExtension.ProvideValue was incorrectly propagating the inherited x:DataType from the parent DataTemplate (e.g., TestItem) onto the binding node itself. When IsXamlCBindingWithSourceCompilationEnabled=true, the runtime binding engine checks whether the source type (MainPage) is assignable from the DataType (TestItem) — which fails — so the source resolves to null and the Command becomes null. ### Description of Change: The fix introduces a way to distinguish between an x:DataType that was explicitly declared on the binding node versus one that was inherited from the enclosing DataTemplate. A new interface IXamlDataTypeProviderWithBindingNodeInfo with an IsDataTypeOnBindingNode property was added to XamlServiceProvider.cs to carry this information through the XAML processing pipeline. In KnownMarkups.cs, the SourceGen guard was updated from if (!hasExplicitSource) to if (!hasExplicitSource || xDataTypeOnBindingNode). This allows TypedBinding code generation to proceed for RelativeSource bindings when x:DataType is explicitly present on the binding node — giving SourceGen the type information it needs to emit a compiled lambda like static (m) => m.ViewModel.ItemTappedCommand instead of a reflective string lookup. This compiled lambda is a direct code reference that the AOT linker can see and preserve, making it safe on iOS Release AOT builds. In BindingExtension.cs, the Runtime inflator was fixed to only propagate DataType when IsDataTypeOnBindingNode=true, preventing the inherited DataType from causing incorrect assignability checks during RelativeSource binding resolution. Similarly, SetPropertiesVisitor.cs was updated for the XamlC path to skip TypedBinding compilation when the DataType is only inherited and not explicitly declared on the binding node. **Tested the behavior in the following platforms:** - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Reference: N/A ### Issues Fixed: Fixes #35564 ### Screenshots | Before | After | |---------|--------| | <Video src="https://github.com/user-attachments/assets/d3fb2c34-ad51-4053-91af-0cccd3dfca0b" Width="300" Height="600"> | <Video src="https://github.com/user-attachments/assets/50b53482-b03e-4b52-997d-abae3b6e9a2a" Width="300" Height="600"> | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…atible in iOS Release Mode (#35798) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details: When MauiXamlInflator=SourceGen + IsAotCompatible=true are set, a Command bound via {RelativeSource AncestorType} inside a CollectionView.ItemTemplate resolves to null at runtime on iOS Release (AOT) builds. ### Root Cause: The issue occurs when MauiXamlInflator=SourceGen and IsAotCompatible=true are set together on an iOS Release build. When a Command is bound using {RelativeSource AncestorType} inside a CollectionView.ItemTemplate, the binding resolves to null at runtime. The core problem is in the MAUI SourceGen (KnownMarkups.cs). When SourceGen processes a binding that has an explicit Source={RelativeSource AncestorType=...}, it sets hasExplicitSource=true. The existing guard if (!hasExplicitSource) then skips the TypedBinding code generation path entirely. This means SourceGen always falls back to generating a regular reflection-based Binding object for any RelativeSource binding — even when x:DataType is explicitly declared on the binding node, which would have given SourceGen all the type information it needs to generate a compiled TypedBinding. A regular Binding resolves its property path at runtime using .NET reflection (PropertyInfo.GetValue). This works perfectly fine in Debug mode because reflection metadata is fully available. However, on iOS Release builds, the AOT linker performs static analysis to trim unused code and metadata. Since the linker only sees a string like "ViewModel.ItemTappedCommand" inside the Binding object — and cannot trace that it will be used reflectively at runtime — it trims the property metadata. When the binding tries to resolve at runtime, the metadata is gone and the binding returns null. A secondary scenario exists for the Runtime inflator path: BindingExtension.ProvideValue was incorrectly propagating the inherited x:DataType from the parent DataTemplate (e.g., TestItem) onto the binding node itself. When IsXamlCBindingWithSourceCompilationEnabled=true, the runtime binding engine checks whether the source type (MainPage) is assignable from the DataType (TestItem) — which fails — so the source resolves to null and the Command becomes null. ### Description of Change: The fix introduces a way to distinguish between an x:DataType that was explicitly declared on the binding node versus one that was inherited from the enclosing DataTemplate. A new interface IXamlDataTypeProviderWithBindingNodeInfo with an IsDataTypeOnBindingNode property was added to XamlServiceProvider.cs to carry this information through the XAML processing pipeline. In KnownMarkups.cs, the SourceGen guard was updated from if (!hasExplicitSource) to if (!hasExplicitSource || xDataTypeOnBindingNode). This allows TypedBinding code generation to proceed for RelativeSource bindings when x:DataType is explicitly present on the binding node — giving SourceGen the type information it needs to emit a compiled lambda like static (m) => m.ViewModel.ItemTappedCommand instead of a reflective string lookup. This compiled lambda is a direct code reference that the AOT linker can see and preserve, making it safe on iOS Release AOT builds. In BindingExtension.cs, the Runtime inflator was fixed to only propagate DataType when IsDataTypeOnBindingNode=true, preventing the inherited DataType from causing incorrect assignability checks during RelativeSource binding resolution. Similarly, SetPropertiesVisitor.cs was updated for the XamlC path to skip TypedBinding compilation when the DataType is only inherited and not explicitly declared on the binding node. **Tested the behavior in the following platforms:** - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Reference: N/A ### Issues Fixed: Fixes #35564 ### Screenshots | Before | After | |---------|--------| | <Video src="https://github.com/user-attachments/assets/d3fb2c34-ad51-4053-91af-0cccd3dfca0b" Width="300" Height="600"> | <Video src="https://github.com/user-attachments/assets/50b53482-b03e-4b52-997d-abae3b6e9a2a" Width="300" Height="600"> | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…isabled Xaml.UnitTests fails in candidate branch (#36592) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details: Issue 1 : UsesReflectionBasedBindingsWhenCompilationOfBindingsWithSourceIsDisabled test case is failed issue 2 : Build error occurs when build "dotnet build src/Controls/samples/Controls.Sample/Maui.Controls.Sample.csproj" in release. ### Root Cause: Issue 1 : PR #35798 introduced a guard in SetPropertiesVisitor.cs to stop XamlC from compiling a TypedBinding whenever Source is RelativeSource / x:Reference and x:DataType isn't declared directly on the binding node ( !xDataTypeIsOnBindingNode ). The problem: this condition is too broad. It was meant to catch one specific dangerous case — x:DataType inherited from an enclosing DataTemplate , which describes the template item type, not the actual RelativeSource / x:Reference target — but it also caught a harmless case: x:DataType inherited from a plain ancestor like ContentPage (no DataTemplate involved), where the inherited type is still perfectly valid to bind against directly. Issue 2 : Release uses the XamlC inflator by default, which fully compiles bindings at build time. PR #35798's new TryGetRelativeSourceAncestorTypeReference logic in SetPropertiesVisitor.cs now treats AncestorType={x:Type ContentPage} as the effective source type for validation, and since SelectedItem / NavigateCommand only exist on BasePage (not ContentPage ), it raises XC0045 and fails the build. ### Description of Change: Issue 1 : The guard condition changed from !xDataTypeIsOnBindingNode to xDataTypeIsInOuterScope — a flag already computed earlier in the method, set to true only when the tree-walk to find x:DataType passes through a DataTemplate node. This precisely targets the one case #35798 actually needed to guard against (DataTemplate-inherited types being wrongly applied to a RelativeSource/x:Reference target), while leaving alone the case where x:DataType is inherited from a normal ancestor (like ContentPage ) or declared directly on the binding node — both of which can safely use the resolved dataTypeNode type as-is. Issue 2 : the fix was applied at the source level in src/Controls/src/Build.Tasks/SetPropertiesVisitor.cs . A new tSourceRefIsAncestorTypeInferred flag now tracks whether the binding's source type came purely from AncestorType inference rather than an explicit x:DataType on the binding node. When property-path resolution against that inferred type fails, and this flag is set, the error is suppressed and the method returns false to gracefully skip TypedBinding compilation — falling back to the original reflection-based Binding , exactly as XamlC always did before PR #35798 for these ambiguous cases. This also mirrors the SourceGen inflator's existing equivalent fallback in KnownMarkups.ProvideValueForBindingExtension . Bindings with an explicit x:DataType , or where the property genuinely doesn't exist anywhere in the runtime ancestor chain, are unaffected and continue to raise XC0045 as intended, preserving PR #35798's original AOT-safety fix. **Tested the behavior in the following platforms:** - [ ] Android - [ ] Windows - [x] iOS - [x] Mac ### Reference: N/A ### Issues Fixed: Fixes #36563
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Issue Details:
When MauiXamlInflator=SourceGen + IsAotCompatible=true are set, a Command bound via {RelativeSource AncestorType} inside a CollectionView.ItemTemplate resolves to null at runtime on iOS Release (AOT) builds.
Root Cause:
The issue occurs when MauiXamlInflator=SourceGen and IsAotCompatible=true are set together on an iOS Release build. When a Command is bound using {RelativeSource AncestorType} inside a CollectionView.ItemTemplate, the binding resolves to null at runtime.
The core problem is in the MAUI SourceGen (KnownMarkups.cs). When SourceGen processes a binding that has an explicit Source={RelativeSource AncestorType=...}, it sets hasExplicitSource=true. The existing guard if (!hasExplicitSource) then skips the TypedBinding code generation path entirely. This means SourceGen always falls back to generating a regular reflection-based Binding object for any RelativeSource binding — even when x:DataType is explicitly declared on the binding node, which would have given SourceGen all the type information it needs to generate a compiled TypedBinding.
A regular Binding resolves its property path at runtime using .NET reflection (PropertyInfo.GetValue). This works perfectly fine in Debug mode because reflection metadata is fully available. However, on iOS Release builds, the AOT linker performs static analysis to trim unused code and metadata. Since the linker only sees a string like "ViewModel.ItemTappedCommand" inside the Binding object — and cannot trace that it will be used reflectively at runtime — it trims the property metadata. When the binding tries to resolve at runtime, the metadata is gone and the binding returns null.
A secondary scenario exists for the Runtime inflator path: BindingExtension.ProvideValue was incorrectly propagating the inherited x:DataType from the parent DataTemplate (e.g., TestItem) onto the binding node itself. When IsXamlCBindingWithSourceCompilationEnabled=true, the runtime binding engine checks whether the source type (MainPage) is assignable from the DataType (TestItem) — which fails — so the source resolves to null and the Command becomes null.
Description of Change:
The fix introduces a way to distinguish between an x:DataType that was explicitly declared on the binding node versus one that was inherited from the enclosing DataTemplate. A new interface IXamlDataTypeProviderWithBindingNodeInfo with an IsDataTypeOnBindingNode property was added to XamlServiceProvider.cs to carry this information through the XAML processing pipeline.
In KnownMarkups.cs, the SourceGen guard was updated from if (!hasExplicitSource) to if (!hasExplicitSource || xDataTypeOnBindingNode). This allows TypedBinding code generation to proceed for RelativeSource bindings when x:DataType is explicitly present on the binding node — giving SourceGen the type information it needs to emit a compiled lambda like static (m) => m.ViewModel.ItemTappedCommand instead of a reflective string lookup. This compiled lambda is a direct code reference that the AOT linker can see and preserve, making it safe on iOS Release AOT builds.
In BindingExtension.cs, the Runtime inflator was fixed to only propagate DataType when IsDataTypeOnBindingNode=true, preventing the inherited DataType from causing incorrect assignability checks during RelativeSource binding resolution. Similarly, SetPropertiesVisitor.cs was updated for the XamlC path to skip TypedBinding compilation when the DataType is only inherited and not explicitly declared on the binding node.
Tested the behavior in the following platforms:
Reference:
N/A
Issues Fixed:
Fixes #35564
Screenshots
Before_35564.mov
After_fix_35564.mov