Skip to content

fix(grid): allow shared size groups to shrink - #21837

Merged
MrJul merged 4 commits into
AvaloniaUI:mainfrom
NathanDrake2406:nathan/fix-21562-shared-size-shrink
Jul 24, 2026
Merged

fix(grid): allow shared size groups to shrink#21837
MrJul merged 4 commits into
AvaloniaUI:mainfrom
NathanDrake2406:nathan/fix-21562-shared-size-shrink

Conversation

@NathanDrake2406

Copy link
Copy Markdown
Contributor

What does the pull request do?

Allows synchronized Grid definitions in a SharedSizeGroup to shrink when the content that established the group minimum becomes smaller or hidden, fixing #21562.

What is the current behavior?

Shared auto columns expand when grouped content grows, but retain that width after the content is hidden. During deferred validation, the group minimum is recomputed through DefinitionBase.MinSize, which includes the previous shared minimum. The old maximum therefore feeds back into the next calculation and becomes self-sustaining.

What is the updated/expected behavior with this PR?

Shared definitions continue to expand together and now shrink together after their intrinsic measured minimum decreases.

Validation on macOS ARM64 with .NET 10:

  • Added Shared_Size_Group_Shrinks_When_Content_Is_Hidden, covering the initial, expanded, and shrunk states across the deferred shared-size layout cycle.
  • Ran GridTests: 80 passed, 0 failed.
  • Ran the full Avalonia.Controls.UnitTests executable: 3,649 total, 3,648 passed, 1 pre-existing skipped, 0 failed.

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

Deferred shared-size validation now aggregates each definition's intrinsic measured _minSize instead of its effective MinSize, which can include the group minimum from the previous layout cycle. This restores the existing long-pole/short-pole invariant and matches the canonical WPF shared-size algorithm.

The commits follow the repository's bug-fix convention: the first commit adds the failing behavioral test, and the second commit contains the fix.

Checklist

  • Added unit tests (if possible)?
  • Added XML documentation to any related classes? No public API was added or changed.
  • Consider submitting a PR to https://github.com/AvaloniaUI/avalonia-docs with user documentation. No documentation change is needed for this internal layout correction.

Breaking changes

None. This restores the expected SharedSizeGroup shrink behavior without changing public API.

Obsoletions / Deprecations

None.

Fixed issues

Fixes #21562

Shared auto columns expand when grouped content becomes visible but keep the expanded width after that content is hidden. Cover the full zero, expanded, and shrunk layout sequence so the stale shared minimum cannot regress unnoticed.
Shared auto definitions reused the previous group minimum while recomputing the next group minimum, so an expanded width became self-sustaining after content shrank. Aggregate each definition's intrinsic measured minimum instead, preserving the shared-size invariant and matching the canonical WPF algorithm.
@NathanDrake2406
NathanDrake2406 marked this pull request as ready for review July 23, 2026 16:26
@avaloniaui-bot

Copy link
Copy Markdown

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

@MrJul MrJul added bug backport-candidate-12.1.x Consider this PR for backporting to 12.1 branch labels Jul 24, 2026

@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.

This matches WPF, which has the same fix:

https://github.com/dotnet/wpf/blob/6ebec6211a69e7d86e24116b29b9e5d571f8f9e3/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/DefinitionBase.cs#L866

However, the fix also needs to change the cached min sizes (they seem to be used only in cyclic dependency cases, worth adding a test?):

dotnet/wpf@1dc9add#diff-2118bc4fdd6a3c621f56e0951cb2595b6ebc330df938e8750e100e08815b4e8e

A grid mixing an auto-column/star-row cell with a star-column/auto-row
cell measures through Grid's cyclic dependency path, which saves and
restores definition min sizes around the repeated measure. The saved
value is the effective min size, so the group minimum is folded into the
definition's own contribution and the group can never shrink below it.
Grid.CacheMinSizes read DefinitionBase.MinSize, which already includes
the shared group's minimum, but ApplyCachedMinSizes writes it back
through SetMinSize, which assigns the definition's own _minSize. A
short-pole definition therefore adopted the group minimum as its own
intrinsic minimum, which reclassified it as a long pole on the next
validation. Long poles with a valid measure are never remeasured, so the
fabricated minimum became unreachable and pinned the group open.

Add DefinitionBase.RawMinSize, the read counterpart of SetMinSize, and
cache that instead so the save/restore pair round-trips the definition's
own contribution. Matches the WPF fix in dotnet/wpf#2270.

@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!

@avaloniaui-bot

Copy link
Copy Markdown

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

@MrJul
MrJul added this pull request to the merge queue Jul 24, 2026
Merged via the queue into AvaloniaUI:main with commit 0ab8b2f Jul 24, 2026
10 checks passed
MrJul pushed a commit that referenced this pull request Jul 29, 2026
* test(grid): reproduce shared size group shrink failure

Shared auto columns expand when grouped content becomes visible but keep the expanded width after that content is hidden. Cover the full zero, expanded, and shrunk layout sequence so the stale shared minimum cannot regress unnoticed.

* fix(grid): allow shared size groups to shrink

Shared auto definitions reused the previous group minimum while recomputing the next group minimum, so an expanded width became self-sustaining after content shrank. Aggregate each definition's intrinsic measured minimum instead, preserving the shared-size invariant and matching the canonical WPF algorithm.

* test(grid): reproduce shared size group stuck on cyclic measure path

A grid mixing an auto-column/star-row cell with a star-column/auto-row
cell measures through Grid's cyclic dependency path, which saves and
restores definition min sizes around the repeated measure. The saved
value is the effective min size, so the group minimum is folded into the
definition's own contribution and the group can never shrink below it.

* fix(grid): restore raw min sizes on the cyclic measure path

Grid.CacheMinSizes read DefinitionBase.MinSize, which already includes
the shared group's minimum, but ApplyCachedMinSizes writes it back
through SetMinSize, which assigns the definition's own _minSize. A
short-pole definition therefore adopted the group minimum as its own
intrinsic minimum, which reclassified it as a long pole on the next
validation. Long poles with a valid measure are never remeasured, so the
fabricated minimum became unreachable and pinned the group open.

Add DefinitionBase.RawMinSize, the read counterpart of SetMinSize, and
cache that instead so the save/restore pair round-trips the definition's
own contribution. Matches the WPF fix in dotnet/wpf#2270.
@MrJul MrJul added backported-12.1.x and removed backport-candidate-12.1.x Consider this PR for backporting to 12.1 branch labels Jul 29, 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.

Grid Columns does not shrink if using SharedSizeGroup

3 participants