Skip to content

TreeView: clicking a row after scrolling away from the selection jumps the viewport and reselects the previous rowΒ #25796

Description

@Xiaoy312

Current behavior πŸ›

In a single-selection TreeView with enough rows to be virtualized, select a row, scroll until that row is out of view, then click another row:

  • The viewport jumps back toward the previously selected row (by about 1,200–1,500 px in the repro) instead of staying where it was.
  • SelectionChanged is raised with the previous row in AddedItems while the clicked row is being selected, so the previous row is briefly selected again.

Expected behavior 🎯

  • Clicking a visible row selects it in place; the viewport does not move.
  • Only the clicked row is reported in AddedItems.

How to reproduce it (as minimally and precisely as possible) πŸ”¬

Repro: k473_LVSSIV.zip

The app builds a TreeView with 30 expanded groups of 25 rows (about 780 visible rows), with IsExpanded and IsSelected two-way bound. A log panel at the bottom records each click ([CLICK]), each SelectionChanged ([SEL]) and any viewport change within a second of a click ([BUG?]).

dotnet run --project Uno120513Repro -f net10.0-desktop
  1. Click a row.
  2. Wheel-scroll down a few screens, until that row is out of view.
  3. Click another visible row: the viewport jumps, and the log shows a [BUG?] line with the offset change, and a [SEL] line adding the previous row.

The same scenario is automated: the Auto check button (or --auto on the command line) runs it 20 times with injected mouse clicks and reports JUMP and PREVIOUS-RESELECTED for each iteration. With --auto the app prints [AUTO] lines to the console and exits with the failure count:

dotnet run --project Uno120513Repro -f net10.0-desktop -- --auto

On Uno.WinUI 7.0.0-dev.2494 all 20 iterations report JUMP and PREVIOUS-RESELECTED.

Workaround πŸ› οΈ

None known.

Affected platforms πŸ“±πŸ’»πŸ–₯️

All platforms 🌍 (reproduced on Desktop (Windows); the code involved is shared by all platforms)

Uno.Sdk version (and other relevant versions) πŸ“¦

Uno.Sdk 7.0.0-dev.95 (Uno.WinUI 7.0.0-dev.2494). Also seen on 6.6 and 6.7.

IDE version πŸ§‘β€πŸ’»

No response

Anything else we need to know? πŸ’¬

In single selection, selecting a node unselects the previous one through TreeViewViewModel.NotifyContainerOfSelectionChange. When the previous node has no container, an Uno-only fallback there (not in WinUI) assigns the node to TreeViewList.SelectedItem regardless of whether it is being selected or unselected. For an unselection, that selects the previous node again, and Selector scrolls it into view; the clicked node's own selection then scrolls back.

Fixing only that fallback exposes a second problem when TreeViewItem.IsSelected is two-way bound, as in the repro: while the previous row has no container, nothing writes the unselection back to its IsSelected, so the data still says true. When the row is scrolled back into view, TreeViewList.PrepareContainerForItemOverride honors that value (the workaround for #15214) and the row takes the selection back from the clicked one.

Activity

  1. added
    kind/bugSomething isn't working
    triage/untriagedIndicates an issue requires triaging or verification
    area/treeview 🌲Categorizes an issue or PR as relevant to the TreeView control
    on Oct 28, 2026
  2. self-assigned this
    on Oct 28, 2026
  3. added theissue type on Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area/treeview 🌲Categorizes an issue or PR as relevant to the TreeView controlkind/bugSomething isn't workingtriage/untriagedIndicates an issue requires triaging or verification

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions