Scroll bar: pause trough hold paging when the thumb reaches the cursor - #12895
Merged
niksedk merged 2 commits intoJul 28, 2026
Merged
Conversation
SubtitleEdit#12894) The theme's trough RepeatButton keeps repeating while IsPressed, and Button only re-evaluates IsPressed on PointerMoved, so a stationary click-and-hold paged straight past the cursor to the end. Handle the trough press in DataGridScrollBarBehavior instead: page once, repeat on a timer, and pause when the thumb reaches the pointer, resuming only if it moves further along, like the Windows scroll bar. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes the DataGrid vertical scrollbar trough “runaway paging” behavior by moving press-and-hold paging logic out of the theme RepeatButton and into DataGridScrollBarBehavior, aligning behavior with Windows (pause when the thumb reaches the stationary pointer; resume only if the pointer moves further in the latched direction).
Changes:
- Added custom press-and-hold trough paging using a
DispatcherTimer, pointer capture, and latched paging direction. - Refactored trough hit-testing into a shared
TryGetTroughPresshelper used by both hold-paging and Shift+click jump. - Added headless UI tests covering single-page paging, stop-on-release, and “thumb press does not page”.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/ui/Logic/DataGridScrollBarBehavior.cs |
Implements custom trough hold-paging (timer + capture + pause-at-pointer) and shares trough hit-testing between behaviors. |
tests/UI/Logic/DataGridScrollBarTroughPagingTests.cs |
Adds headless regression tests for basic trough paging and release/thumb-press behavior. |
Comment on lines
+186
to
+190
| private static void TickTroughHoldPaging(DataGrid grid, ScrollBar verticalScrollBar, TroughHoldState holdState) | ||
| { | ||
| var track = verticalScrollBar.GetVisualDescendants().OfType<Track>().FirstOrDefault(); | ||
| if (track == null || track.Bounds.Height <= 0) | ||
| var thumb = track?.Thumb; | ||
| if (track == null || thumb == null) |
Comment on lines
+201
to
209
| // Pause (not stop) once the thumb has reached the pointer: paging resumes if the | ||
| // pointer moves further in the latched direction, like the Windows scroll bar. | ||
| var shouldPage = holdState.PageDown | ||
| ? posY > thumb.Bounds.Y + thumb.Bounds.Height | ||
| : posY < thumb.Bounds.Y; | ||
| if (shouldPage) | ||
| { | ||
| return; | ||
| PageOnce(grid, verticalScrollBar, holdState.PageDown); | ||
| } |
…sume Review follow-up on SubtitleEdit#12895: - Cache the Track at press time instead of walking the visual tree on every 100 ms tick (Copilot review). - Stop the repeat if the pointer capture is gone, so a missed release cannot leave the timer paging. - Skip the page (and the ProcessVerticalScroll call) once the value is clamped at the end of the range. - Do not swallow the press when ProcessVerticalScroll is missing: without it a page would move the thumb but not the rows, so leave it to the theme. - Keep the hold state on the scroll bar instead of in a closure. - Tests: the headless dispatcher never fires a DispatcherTimer, so the repeat is stepped by hand - covers pause at the pointer, resume when it moves further, no reverse when it moves back, and release stopping the repeat (Copilot review). Verified by mutation: each test fails when its behavior is removed. - Trim comments. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Member
|
Pushed a follow-up commit addressing both review comments:
Also while in there:
|
Merged
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.
Fixes #12894
Summary
Test plan
dotnet test tests/UI/UITests.csproj— all tests pass (3 new in DataGridScrollBarTroughPagingTests)🤖 Generated with Claude Code