Skip to content

fix: Support StylableElement for styles inside ContainerQueries - #22167

Merged
MrJul merged 4 commits into
AvaloniaUI:mainfrom
OleRoss:fix/container-queries-considering-logical-parent
Oct 16, 2026
Merged

MrJul merged 4 commits into
AvaloniaUI:mainfrom
OleRoss:fix/container-queries-considering-logical-parent

Conversation

@OleRoss

@OleRoss OleRoss commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

What does the pull request do?

StyleSelectors work on stylable elements. But for container queries, the query selection silently limits this to visuals only (see #22166 for details).

This PR removes that restriction. For a non-visual StyledElement, container queries find the first Visual in its logical ancestors and use that visual as the starting point when searching for a matching container.

The existing behavior for visual targets remains unchanged.

What is the current behavior?

Only classes extending Visual work; when extending only ' StyledElement', styles are silently ignored.

What is the updated/expected behavior with this PR?

Works

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

Container-query activators now accept a StyledElement instead of requiring a Visual.

For a visual target, container lookup still starts with its visual parent.

For a non-visual target, the activator:

  • finds the first Visual in the target's logical ancestors;
  • takes that visual when matching a container
  • tracks logical attachment and detachment

Checklist

Breaking changes

Obsoletions / Deprecations

Fixed issues

Fixes #22166

@MrJul MrJul added bug backport-candidate-12.1.x Consider this PR for backporting to 12.1 branch labels Sep 7, 2026
@avaloniaui-bot

Copy link
Copy Markdown

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

@avaloniaui-bot

Copy link
Copy Markdown

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

@grokys
grokys requested review from emmauss and a lite review from Copilot September 9, 2026 14:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The updated container-query base can retain a stale cached container in some detach/provider-clear scenarios, which can block re-initialization and should be corrected before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR fixes container queries (WidthQuery/HeightQuery and query combinators) so they can target non-Visual StyledElements by resolving the first Visual in the element’s logical ancestor chain and using that as the starting point for container lookup, while keeping the existing behavior for Visual targets.

Changes:

  • Updated container-query activators and query evaluation to accept StyledElement (not only Visual) and to resolve a Visual via logical ancestors when needed.
  • Updated AND/OR query evaluation and activator builders to operate on StyledElement.
  • Added unit tests covering non-visual targets, logical reparenting scenarios, and ensuring a container doesn’t query itself.
File summaries
File Description
tests/Avalonia.Base.UnitTests/Styling/ContainerTests.cs Adds coverage for non-visual container-query targets, reparenting tracking, and “container doesn’t query itself”.
src/Avalonia.Base/Styling/ScreenQueries.cs Removes Visual-only restriction for width/height queries and routes evaluation through StyledElement-based container lookup.
src/Avalonia.Base/Styling/OrQuery.cs Allows OR query evaluation for non-visual styled elements by removing Visual gating.
src/Avalonia.Base/Styling/AndQuery.cs Allows AND query evaluation for non-visual styled elements by removing Visual gating.
src/Avalonia.Base/Styling/Activators/ScreenActivator.cs Updates width/height activators to accept StyledElement targets.
src/Avalonia.Base/Styling/Activators/OrQueryActivatorBuilder.cs Switches builder from Visual to StyledElement to support non-visual targets.
src/Avalonia.Base/Styling/Activators/OrQueryActivator.cs Updates constructor to accept StyledElement and pass it to the shared container-query base.
src/Avalonia.Base/Styling/Activators/ContainerQueryActivatorBase.cs Core change: resolves a Visual for non-visual targets via logical ancestors, tracks logical attach/detach, and adjusts container lookup accordingly.
src/Avalonia.Base/Styling/Activators/AndQueryActivatorBuilder.cs Switches builder from Visual to StyledElement to support non-visual targets.
src/Avalonia.Base/Styling/Activators/AndQueryActivator.cs Updates constructor to accept StyledElement and pass it to the shared container-query base.
Review details
  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +79 to +83

if (_visual is { } oldVisual)
{
oldVisual.AttachedToVisualTree -= Visual_AttachedToVisualTree;
oldVisual.DetachedFromVisualTree -= Visual_DetachedFromVisualTree;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I am not sure if this is relevant to this PR. As far as I can see, the part

if (_currentScreenSizeProvider is { } && Container.GetQueryProvider(_currentScreenSizeProvider) is { } provider)
{
    provider.WidthChanged -= WidthChanged;
    provider.HeightChanged -= HeightChanged;
    _currentScreenSizeProvider = null;
}

predates this PR and was previously called by Deinitialize. But I can move the field outside as well, if thats desired.

@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

NuGet packages

The packages for this pull request have been published (workflow run):

@emmauss

emmauss commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Sorry for the late reply. Could you add a sample demonstrating the added behavior?

@OleRoss

OleRoss commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Hi @emmauss, no worries. I added an example to the Container Queries page of the control gallery:
image

I was not sure where you wanted it. we could also add it to the TableView page directly (because this is the main contender for a non-visual StyledElement that i know of) (not included yet):
image

@emmauss

emmauss commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

It would be best for this specific one to be in the TableView sample

Demonstrates a container query that targets a non-visual StyledElement, as requested in the PR review. The option row wraps so that it does not clip while the page is narrowed.
@OleRoss
OleRoss force-pushed the fix/container-queries-considering-logical-parent branch from 811efed to 604b21d Compare October 13, 2026 12:00
@OleRoss

OleRoss commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Its now part of the tableview example
tableview-container-query

@emmauss emmauss left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@MrJul
MrJul added this pull request to the merge queue Oct 15, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 15, 2026
@MrJul
MrJul added this pull request to the merge queue Oct 16, 2026
Merged via the queue into AvaloniaUI:main with commit c1a1246 Oct 16, 2026
11 checks passed
MrJul pushed a commit that referenced this pull request Nov 2, 2026
* fix: Support StylableElement for styles inside ContainerQueries

* chore: Add container query sample for TableView columns

Demonstrates a container query that targets a non-visual StyledElement, as requested in the PR review. The option row wraps so that it does not clip while the page is narrowed.
@MrJul MrJul added backported-12.1.x and removed backport-candidate-12.1.x Consider this PR for backporting to 12.1 branch labels Nov 2, 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.

Container queries (WidthQuery/HeightQuery) only work for Visuals

5 participants