Fix MAUIG2045 false positive with x:Reference source in DataTemplate#34501
Fix MAUIG2045 false positive with x:Reference source in DataTemplate#34501StephaneDelcroix merged 1 commit intomainfrom
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34501Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34501" |
|
/azp run maui-pr-devicetests, maui-pr-uitests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
This PR addresses a MAUIG2045 false positive in the XAML source generator when a binding inside a DataTemplate uses an explicit Source={x:Reference ...}. The fix updates the source generator’s decision logic so it won’t attempt to compile bindings against the DataTemplate’s x:DataType when the binding source is explicitly overridden via x:Reference, preventing incorrect “property not found” diagnostics.
Changes:
- Update SourceGen binding analysis to treat
Source={x:Reference ...}similarly toRelativeSourcefor compiled-binding eligibility. - Add a SourceGen unit test asserting MAUIG2045 is not emitted for the reported scenario.
- Add a Xaml.UnitTests issue reproduction page (
Maui34490) covering the same binding pattern across inflators.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Controls/src/SourceGen/KnownMarkups.cs | Extends HasRelativeSourceBinding to detect ReferenceExtension / Reference so compiled binding is skipped when Source is x:Reference. |
| src/Controls/tests/SourceGen.UnitTests/BindingDiagnosticsTests.cs | Adds regression test ensuring MAUIG2045 is not reported for x:Reference source in a DataTemplate. |
| src/Controls/tests/Xaml.UnitTests/Issues/Maui34490.xaml | Adds issue XAML reproducing the binding pattern (x:Reference to page root inside DataTemplate). |
| src/Controls/tests/Xaml.UnitTests/Issues/Maui34490.xaml.cs | Adds issue test; includes a SourceGen diagnostic assertion path for MAUIG2045. |
8fbe072 to
29bf311
Compare
|
/azp run maui-pr-devicetests, maui-pr-uitests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
c03565d to
86dc2db
Compare
|
/azp run maui-pr-devicetests, maui-pr-uitests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
86dc2db to
bf53c5c
Compare
|
/azp run maui-pr-devicetests, maui-pr-uitests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
PureWeen
left a comment
There was a problem hiding this comment.
Re-Review: New x:Reference Type Resolution Approach
The new commit takes a fundamentally better approach (resolve x:Reference target types and compile against them), but introduces a build-breaking regression confirmed by CI.
Previous Findings Status
- Finding 1 (x:DataType regression): ✅ FIXED — x:Reference bindings are now compiled against the resolved type instead of being blanket-skipped.
- Finding 2 (SourceGen page instantiation): ✅ FIXED — SourceGen branch no longer skips page instantiation in
Maui34490.xaml.cs. - Finding 3 (inaccurate comment): ✅ FIXED — Updated comment accurately describes the three-way behavior.
- Finding 4 (namespace URI check):
⚠️ STILL PRESENT (pre-existing) —TryResolveXReferenceSourceTypechecksXmlType.Namewithout verifyingNamespaceUri, same pattern asHasRelativeSourceBinding.
New Findings
[BUG — CI-BREAKING] BindingContext.Property path emits MAUIG2045 → build error
KnownMarkups.cs — TryResolveXReferenceSourceType + TryParsePath
When Source is {x:Reference SomePage} and Path is BindingContext.SomeCommand:
TryResolveXReferenceSourceTyperesolvesSomePage→ContentPageTryParsePathwalks:BindingContextfound onBindableObject(typed asobject) ✅SomeCommandnot found onobject→ emits MAUIG2045 unconditionally → returns false- Falls back to runtime binding (correct) — but the diagnostic is already emitted
Directory.Build.propssetsTreatWarningsAsErrors=true→ build error
Before this PR: these bindings never entered compilation (no x:DataType → TryGetXDataType returned null → no compilation → no warning).
After this PR: TryResolveXReferenceSourceType provides a type → compilation is attempted → MAUIG2045 emitted on the object hop.
CI confirms this — all 3 failing jobs (Build Sample App, Build Sample App (CoreCLR), Build Sample App (Material3)) fail with 4 unique MAUIG2045 errors:
| File | Path | Property not found on object |
|---|---|---|
Issue8295.xaml:13,25 |
BindingContext.TbGlyph |
TbGlyph |
Issue1455.xaml:16,29 |
BindingContext.IsContextActionsLegacyModeEnabled |
IsContextActionsLegacyModeEnabled |
Issue6932_emptyviewtemplate.xaml:16 |
BindingContext.EmptyTemplateAutomationId |
EmptyTemplateAutomationId |
Issue2951.xaml:17 |
BindingContext.ButtonTapped |
ButtonTapped |
Additionally, 9+ files in Controls.Sample use the same pattern (SwipeView galleries with BindingContext.FavouriteCommand, BindingContext.DeleteCommand, etc.) and will break when those builds run.
Root cause: TryParsePath emits diagnostics unconditionally. For x:DataType-driven compilation, this makes sense (developer explicitly declared the type). For x:Reference-driven compilation, this is a false positive — the generator is opportunistically trying to compile what was always a runtime binding.
Suggested fix: When the data type was resolved via TryResolveXReferenceSourceType (not TryGetXDataType), either:
- Suppress MAUIG2045 by passing a flag to
TryCompileBinding/TryParsePathto skip the diagnostic - Check if the first path segment resolves to
objectand bail before attempting further compilation - Wrap the compilation attempt and discard any diagnostics on failure (treat as "best effort")
[OBSERVATION] Wider behavioral change for all x:Reference bindings
The PR description focuses on DataTemplate scenarios, but the change affects all {Binding Source={x:Reference X}, Path=P} patterns globally. There are 46 such bindings in TestCases.HostApp and 135 in Controls.Sample. Most will compile successfully (e.g., {Binding Source={x:Reference slider}, Path=Value} → Slider.Value exists), but the BindingContext.Property subset will break. This broader scope should be documented in the PR description.
Summary
The approach is sound — resolving x:Reference types for compiled bindings is the right direction. The blocking issue is that TryParsePath unconditionally emits MAUIG2045 when it hits an object type in the path chain, and this triggers build failures in TreatWarningsAsErrors projects. Once that diagnostic emission is gated for x:Reference-resolved bindings, the CI failures should clear.
bf53c5c to
ab9e895
Compare
|
/azp run maui-pr-devicetests, maui-pr-uitests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
dfaced4 to
8df9cf7
Compare
|
/azp run maui-pr |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run maui-pr |
|
Azure Pipelines successfully started running 1 pipeline(s). |
When Source={x:Reference} is used in a binding inside a DataTemplate,
the source generator incorrectly resolves the Path against the
DataTemplate's x:DataType instead of the referenced element's type.
The fix resolves the x:Reference target's type via namescope lookup
and compiles the binding path against that type. For example,
Source={x:Reference PageRoot} with Path=BindingContext.SelectItemCommand
now resolves against ContentPage (the referenced element) instead of
ItemModel (the DataTemplate's x:DataType).
Fixes #34490
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
8df9cf7 to
c9f0575
Compare
|
/azp run maui-pr-devicetests, maui-pr-uitests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
… source in DataTemplate (#34525) <!-- 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! ## Description Backport of #34501 to `release/10.0.1xx-sr5`. When a binding uses `Source={x:Reference}`, the source generator was incorrectly validating the binding path against `x:DataType` instead of the referenced element, producing a false MAUIG2045 warning. This fix detects explicit binding sources (both `RelativeSource` and `x:Reference`) and skips compilation, falling back to runtime binding. Fixes #34490 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…otnet#34501) <!-- 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! ## Description Fixes dotnet#34490 When `Source={x:Reference}` is used in a binding inside a `DataTemplate`, the XAML source generator incorrectly resolves the `Path` against the DataTemplate's `x:DataType` instead of the referenced element's type. This causes a false **MAUIG2045** warning for patterns like `Path=BindingContext.SelectItemCommand`. ### Example triggering the false positive ```xml <DataTemplate x:DataType="models:ItemModel"> <Button Command="{Binding Source={x:Reference PageRoot}, Path=BindingContext.SelectItemCommand}" /> </DataTemplate> ``` The source generator tries to find `BindingContext` on `ItemModel` (the DataTemplate's `x:DataType`) instead of recognizing that the binding source is the referenced element. ## Root Cause `HasRelativeSourceBinding()` in `KnownMarkups.cs` only checked for `RelativeSourceExtension`/`RelativeSource` when deciding whether to skip compiled binding generation. It did not account for `ReferenceExtension`/`Reference` (`x:Reference`), so bindings with `Source={x:Reference}` were still compiled against the current `x:DataType` scope. ## Fix Extended `HasRelativeSourceBinding()` to also detect `ReferenceExtension` and `Reference` (the two forms of `x:Reference`). When detected, the source generator skips compiled binding and falls back to runtime binding — the same behavior already used for `RelativeSource` bindings. ## Tests - **SourceGen.UnitTests**: `BindingWithXReferenceSourceInDataTemplate_DoesNotReportPropertyNotFound` — verifies no MAUIG2045 diagnostic is emitted - **Xaml.UnitTests**: `Maui34490` — XAML page reproducing the exact issue scenario, tested across all inflators (Runtime, XamlC, SourceGen) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…34513) <!-- 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! ## Description Follow-up to #34501 (which targets `main` with a minimal fix). This PR enhances x:Reference binding compilation for `net11.0` by **resolving the referenced element's type** and compiling the binding against it, instead of skipping compilation entirely. ### What it does When a binding uses `Source={x:Reference Name}`, the source generator now: 1. **Walks namescopes** to find the referenced element's type (e.g., `ContentPage` for `x:Reference PageRoot`, `Label` for `x:Reference StatusLabel`) 2. **Compiles the binding** against the resolved type when the path is fully resolvable (e.g., `Path=Text` on a `Label`) 3. **Falls back silently** to runtime binding when the path can't be resolved (e.g., `Path=BindingContext.SelectItemCommand` where `BindingContext` is `object`) ### Key design decision: `out Diagnostic?` on `TryParsePath` The MAUIG2045 ("property not found") diagnostic is now returned as an `out` parameter from `TryParsePath`/`TryCompileBinding` instead of being emitted directly. This lets the caller decide: - **x:DataType bindings**: emit MAUIG2045 as before (no behavior change) - **x:Reference bindings**: suppress MAUIG2045 and fall back to runtime (these were never compiled before, so a new warning would be a regression) ### Tests added - `BindingWithXReferenceSourceInDataTemplate_DoesNotReportFalsePositive` — verifies no false MAUIG2045 for `Path=BindingContext.X` - `BindingWithXReferenceToNonRootElement_ResolvesCorrectType` — verifies `Path=Text` against a referenced `Label` compiles with no warnings - `Maui34490.xaml` — XAML unit test reproducing the original issue - Updated `Gh3606` test — binding to `Content` via x:Reference now compiles Fixes #34490 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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!
Description
Fixes #34490
When
Source={x:Reference}is used in a binding inside aDataTemplate, the XAML source generator incorrectly resolves thePathagainst the DataTemplate'sx:DataTypeinstead of the referenced element's type. This causes a false MAUIG2045 warning for patterns likePath=BindingContext.SelectItemCommand.Example triggering the false positive
The source generator tries to find
BindingContextonItemModel(the DataTemplate'sx:DataType) instead of recognizing that the binding source is the referenced element.Root Cause
HasRelativeSourceBinding()inKnownMarkups.csonly checked forRelativeSourceExtension/RelativeSourcewhen deciding whether to skip compiled binding generation. It did not account forReferenceExtension/Reference(x:Reference), so bindings withSource={x:Reference}were still compiled against the currentx:DataTypescope.Fix
Extended
HasRelativeSourceBinding()to also detectReferenceExtensionandReference(the two forms ofx:Reference). When detected, the source generator skips compiled binding and falls back to runtime binding — the same behavior already used forRelativeSourcebindings.Tests
BindingWithXReferenceSourceInDataTemplate_DoesNotReportPropertyNotFound— verifies no MAUIG2045 diagnostic is emittedMaui34490— XAML page reproducing the exact issue scenario, tested across all inflators (Runtime, XamlC, SourceGen)