Fix the expander never collapsing its content - #3329
Merged
Conversation
The scoped batch's Completed handler compares _tracker against a value captured with a post-increment, so the comparison was (n + 1) == n and never held. The handler is what applies Visibility.Collapsed after the collapse animation, and PopupRoot.Visibility is set to Visible unconditionally just above it, so collapsed content stayed visible and kept participating in layout — hidden only by PopupHost.Height = 0 and the negative margin. Pre-increment gives the guard its intended meaning: apply the final visibility unless a newer toggle has started since this batch began. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
FrayxRulez
added a commit
that referenced
this pull request
Aug 10, 2026
The scoped batch's Completed handler compares _tracker against a value captured with a post-increment, so the comparison was (n + 1) == n and never held. The handler is what applies Visibility.Collapsed after the collapse animation, and PopupRoot.Visibility is set to Visible unconditionally just above it, so collapsed content stayed visible and kept participating in layout — hidden only by PopupHost.Height = 0 and the negative margin. Pre-increment gives the guard its intended meaning: apply the final visibility unless a newer toggle has started since this batch began. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
SettingsExpander.OnExpandedChangedguards the scoped batch's completion against a newertoggle:
_tracker++returns the value before the increment, so by the time the handler runs thecomparison is
(n + 1) == n. It is never true, and the body never executes — on any toggle,not just a superseded one.
That handler is the only thing that applies
Visibility.Collapsed, andPopupRoot.Visibilityis set to
Visibleunconditionally a few lines above:So a collapsed expander keeps its content
Visiblein the tree, still measured and arrangedon every pass, hidden only by
Height = 0on the host and a negative bottom margin.Fix
Pre-increment, so
trackeridentifies this run:The guard then means what it was written to mean — apply the final visibility unless a newer
toggle has started since this batch began. The stale-completion case it was added for still
works, because a subsequent toggle bumps
_trackerpast the captured value.History
The guard arrived in
a3a98e6d31together with the switch from the capturednewValueto the_expandedfield, which is what makes the intent unambiguous. The laterc67940f5e6("Fixexpander layout cycle") removed a
SizeChangedhandler that rewrote the same margin, and isunrelated to this.
Verification
Not built or run — a UWP/.NET Native build is not available in the environment this was
prepared in. The edited file was checked with Roslyn (
CSharpSyntaxTree.ParseText) and parseswith no syntax errors; that confirms syntax only, not type checking. Worth a visual check that
collapsing still animates rather than snapping, since the collapse now ends in a real
visibility change.
🤖 Generated with Claude Code