Skip to content

Fix #20625: fix compiled binding DataContext inference in ItemTemplate - #21248

Merged
MrJul merged 4 commits into
AvaloniaUI:masterfrom
JoaoMSSCruz:fix/datacontext-itemtemplate
May 15, 2026
Merged

Fix #20625: fix compiled binding DataContext inference in ItemTemplate#21248
MrJul merged 4 commits into
AvaloniaUI:masterfrom
JoaoMSSCruz:fix/datacontext-itemtemplate

Conversation

@JoaoMSSCruz

Copy link
Copy Markdown
Contributor

The Sandbox repro failed with AVLN2100/AVLN2000 when compiled bindings were used with ItemTemplate and name-based DataContext access.

Root causes:

  • No fallback DataContext type was inferred for the root object when x:DataType was absent.
  • Name-scope lookup could capture stale DataContext metadata from an unrelated traversal branch, causing #ListBoxRoot.DataContext to incorrectly resolve to the item type.

Fixes:

  • Add root-level DataContext fallback inference in AvaloniaXamlIlDataContextTypeTransformer.
  • Update ScopeRegistrationFinder to resolve DataContext from the current ancestor stack when the matching name is found.
  • Preserve first-match semantics and prefer root namescope lookup before deferred scopes in name binding resolution.
  • Add and expand unit tests for ItemTemplate and nested namescope scenarios, including mismatched runtime DataContext behavior.

What does the pull request do?

This PR fixes an issue where shorthand DataContext bindings (introduced in Avalonia 11.3.0) fail to resolve correctly when preceded by an ItemTemplate within the same view. It addresses the compiled binding errors (AVLN2100 and AVLN2000) by correcting how the XAML compiler infers the data context type during scope registration and name lookup.

What is the current behavior?

Currently, if an ItemTemplate (such as one inside a ComboBox) is declared before an element using a shorthand DataContext binding (e.g., {Binding #ListBoxRoot.DataContext.ButtonCommand} inside a ListBox), the compiler incorrectly captures stale DataContext metadata from the unrelated traversal branch. It evaluates the target element's DataContext as matching the preceding ItemTemplate's context rather than the actual parent, causing the application to crash during compilation.

What is the updated/expected behavior with this PR?

The DataContext now correctly resolves to the parent element it is assigned to. Shorthand bindings placed after other ItemTemplate definitions no longer confuse the compiler's scope lookup, allowing the project to build and the bindings to resolve accurately.

How was the solution implemented (if it's not obvious)?

Added root-level DataContext fallback inference in AvaloniaXamlIlDataContextTypeTransformer to handle cases where x:DataType is absent.
Updated ScopeRegistrationFinder so that when a matching name is found, it resolves the DataContext from the current ancestor stack rather than capturing stale context from previous branches.
Preserved first-match semantics, giving preference to the root namescope lookup over deferred scopes during name binding resolution.
Added and expanded unit tests covering nested namescopes, ItemTemplate scenarios, and mismatched runtime DataContext behavior.

Checklist

Breaking changes

None.

Obsoletions / Deprecations

None.

Fixed issues

Fixes #20625

…temTemplate

The Sandbox repro failed with AVLN2100/AVLN2000 when compiled
bindings were used with ItemTemplate and name-based DataContext
access.

Root causes:
- No fallback DataContext type was inferred for the root object when
  x:DataType was absent.
- Name-scope lookup could capture stale DataContext metadata from an
  unrelated traversal branch, causing #ListBoxRoot.DataContext to
  incorrectly resolve to the item type.

Fixes:
- Add root-level DataContext fallback inference in
  AvaloniaXamlIlDataContextTypeTransformer.
- Update ScopeRegistrationFinder to resolve DataContext from the
  current ancestor stack when the matching name is found.
- Preserve first-match semantics and prefer root namescope lookup
  before deferred scopes in name binding resolution.
- Add and expand unit tests for ItemTemplate and nested namescope
  scenarios, including mismatched runtime DataContext behavior.

Signed-off-by: João Cruz <joaosantaremdacruz@tecnico.ulisboa.pt>
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.1.999-cibuild0065009-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@cla-avalonia

cla-avalonia commented Apr 22, 2026

Copy link
Copy Markdown
Collaborator
  • All contributors have signed the CLA.

@JoaoMSSCruz

Copy link
Copy Markdown
Contributor Author

@cla-avalonia agree

@MrJul MrJul added bug area-xaml area-bindings backport-candidate-12.0.x Consider this PR for backporting to 12.0 branch labels Apr 23, 2026
@MrJul

MrJul commented Apr 23, 2026

Copy link
Copy Markdown
Member

No fallback DataContext type was inferred for the root object when x:DataType was absent.
Added root-level DataContext fallback inference in AvaloniaXamlIlDataContextTypeTransformer to handle cases where x:DataType is absent.

This is not how data contexts work, this change should be completely removed from the PR.

Comment thread tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs Outdated
Address review feedback to reduce test complexity in XamlIlTests.

This change removes per-test UserControl helper classes and command
scaffolding that were not required to validate the compiler behavior.
Tests now use inline XAML in each [Fact] and shared lightweight mock
types for root and item data.

The compiled binding scenarios are still covered, including root
fallback inference and named DataContext resolution with ItemTemplate
and nested namescopes, but with less boilerplate and better readability.
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.1.999-cibuild0065035-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@JoaoMSSCruz
JoaoMSSCruz requested a review from MrJul April 24, 2026 14:28
// starting type for compiled bindings. Falling back to the root CLR type
// allows expressions to compile and avoids stale inference from unrelated
// branches, while runtime DataContext semantics remain unchanged.
inferredDataContextTypeNode = new AvaloniaXamlIlDataContextTypeMetadataNode(on, on.Type.GetClrType());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned, this change isn't related to the issue and isn't necessary. We do not want automatic inference to fall back to the root type.

Address review feedback by removing the automatic fallback inference
to the root type in AvaloniaXamlIlDataContextTypeTransformer, as it
is not necessary to fix the issue and is not desired behavior.

Also removes the unit tests that validated this specific fallback.
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.1.999-cibuild0065234-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@JoaoMSSCruz
JoaoMSSCruz requested a review from MrJul May 5, 2026 14:51

@MrJul MrJul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@MrJul
MrJul enabled auto-merge May 15, 2026 11:34
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.1.999-cibuild0065425-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@MrJul
MrJul added this pull request to the merge queue May 15, 2026
Merged via the queue into AvaloniaUI:master with commit 837e1aa May 15, 2026
11 checks passed
MrJul added a commit to MrJul/Avalonia that referenced this pull request May 28, 2026
…temTemplate (AvaloniaUI#21248)

* Fix AvaloniaUI#20625: fix compiled binding DataContext inference in ItemTemplate

The Sandbox repro failed with AVLN2100/AVLN2000 when compiled
bindings were used with ItemTemplate and name-based DataContext
access.

Root causes:
- No fallback DataContext type was inferred for the root object when
  x:DataType was absent.
- Name-scope lookup could capture stale DataContext metadata from an
  unrelated traversal branch, causing #ListBoxRoot.DataContext to
  incorrectly resolve to the item type.

Fixes:
- Add root-level DataContext fallback inference in
  AvaloniaXamlIlDataContextTypeTransformer.
- Update ScopeRegistrationFinder to resolve DataContext from the
  current ancestor stack when the matching name is found.
- Preserve first-match semantics and prefer root namescope lookup
  before deferred scopes in name binding resolution.
- Add and expand unit tests for ItemTemplate and nested namescope
  scenarios, including mismatched runtime DataContext behavior.

Signed-off-by: João Cruz <joaosantaremdacruz@tecnico.ulisboa.pt>

* Fix AvaloniaUI#20625: simplify compiled binding regression tests

Address review feedback to reduce test complexity in XamlIlTests.

This change removes per-test UserControl helper classes and command
scaffolding that were not required to validate the compiler behavior.
Tests now use inline XAML in each [Fact] and shared lightweight mock
types for root and item data.

The compiled binding scenarios are still covered, including root
fallback inference and named DataContext resolution with ItemTemplate
and nested namescopes, but with less boilerplate and better readability.

* Fix AvaloniaUI#20625: remove automatic DataContext fallback to root type

Address review feedback by removing the automatic fallback inference
to the root type in AvaloniaXamlIlDataContextTypeTransformer, as it
is not necessary to fix the issue and is not desired behavior.

Also removes the unit tests that validated this specific fallback.

---------

Signed-off-by: João Cruz <joaosantaremdacruz@tecnico.ulisboa.pt>
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
@MrJul MrJul added backported-12.0.x and removed backport-candidate-12.0.x Consider this PR for backporting to 12.0 branch labels May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Shorthand DataContext binding breaks after using an itemtemplate

4 participants