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
- Bind a left hierarchical
NavigationView with two parent groups (e.g., Group A and Group B) containing child items in ObservableCollection.
- Expand both Group A and Group B.
- Select a child item under Group A (
SelectedItem = child1). Notice Group A has IsChildSelected = true.
- Move
child1 from Group A's child collection to Group B's child collection, and ensure SelectedItem is child1.
- Observe that Group A's container still has
IsChildSelected = true.
- Collapse Group A.
- 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:
Describe the bug
When using a hierarchical
NavigationView, moving a currently selected item from one parent item/group to another leavesIsChildSelectedset totrueon its former ancestors.As a result:
SelectedItemstill points to the original leaf in its new location.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
NavigationViewwith two parent groups (e.g., Group A and Group B) containing child items inObservableCollection.SelectedItem = child1). Notice Group A hasIsChildSelected = true.child1from Group A's child collection to Group B's child collection, and ensureSelectedItemischild1.IsChildSelected = true.SelectedItemremainschild1under Group B.Actual behavior
Former ancestor containers retain
IsChildSelected = trueafter 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
IsChildSelectedcleared when their selected descendant is reparented or no longer under that ancestor. Only current active ancestors ofSelectedItemshould reportIsChildSelected = 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: