microsoft / microsoft/microsoft-ui-xaml

NavigationView: Moving selected item between groups leaves IsChildSelected=true on former ancestors

Open
#11,927 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area-NavigationView bug team-Controls
Dominant language
C++
Stars
8.4k
Forks
942
Avg merge
2d 7h
Merged PRs (30d)
105

Description

### Describe the bug

When using a hierarchical `NavigationView`, moving a currently selected item from one parent item/group to another leaves `IsChildSelected` set to `true` on its former ancestors.

As a result:
- Collapsing an unrelated former parent moves the selection indicator to that group, even though `SelectedItem` still points to the original leaf in its new location.
- Inserting a root item before the ancestor and selecting a top-level item can also leave the original parent marked as child-selected.

### Why is this important?

In apps where items are dynamically categorized into hierarchical groups (e.g. grouping active/pending tasks, chat sessions, or folders), reparenting the currently selected item corrupts the ancestor selection visual states. When the user collapses the former group, it mistakenly claims the active selection indicator, misleading the user about which item is selected.

### Steps to reproduce the bug

1. Bind a left hierarchical `NavigationView` with two parent groups (e.g., Group A and Group B) containing child items in `ObservableCollection`.
2. Expand both Group A and Group B.
3. Select a child item under Group A (`SelectedItem = child1`). Notice Group A has `IsChildSelected = true`.
4. Move `child1` from Group A's child collection to Group B's child collection, and ensure `SelectedItem` is `child1`.
5. Observe that Group A's container still has `IsChildSelected = true`.
6. Collapse Group A.
7. Observe that Group A's selection indicator becomes active, incorrectly displaying the selection indicator on Group A while `SelectedItem` remains `child1` under Group B.

### Actual behavior

Former ancestor containers retain `IsChildSelected = true` after the selected child item is reparented to another group. Collapsing the former parent displays a phantom selection indicator on that container.

### Expected behavior

Former ancestors should have `IsChildSelected` cleared when their selected descendant is reparented or no longer under that ancestor. Only current active ancestors of `SelectedItem` should report `IsChildSelected = true`.

### Screenshots

_No response_

### NuGet package version

Microsoft.WindowsAppSDK 1.6+ (reproduced on Windows App SDK 2.4.0 / .NET 10 standalone native app)

### Windows version

Windows 11 (24H2): Build 26100, Windows 11 (23H2): Build 22631

### Additional context

In `controls/dev/NavigationView/NavigationView.cpp#L2494-L2511` (`OnSelectionModelSelectionChanged`):
Ancestor unselection and cleanup resolves through the cached index path (`m_lastSelectedItemIndexPath`), which does not accurately track ancestor state changes when the item collection/hierarchy mutates or when items are moved between containers.

Cross-reference:
- Uno Platform issue: https://github.com/unoplatform/uno/issues/24508
- Uno Platform PR: https://github.com/unoplatform/uno/pull/24509

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in controls/dev/NavigationView/NavigationView.cpp at OnSelectionModelSelectionChanged, especially lines 2494-2511, and trace how m_lastSelectedItemIndexPath handles ancestor cleanup. Reproduce moving a selected child between groups, then verify that former ancestors clear IsChildSelected while only the current ancestors retain it.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop, frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.