Skip to content

Fix SelectionChanged not raised on collection Reset#20942

Open
NathanDrake2406 wants to merge 1 commit intoAvaloniaUI:masterfrom
NathanDrake2406:fix/listbox-selectionchanged-on-reset
Open

Fix SelectionChanged not raised on collection Reset#20942
NathanDrake2406 wants to merge 1 commit intoAvaloniaUI:masterfrom
NathanDrake2406:fix/listbox-selectionchanged-on-reset

Conversation

@NathanDrake2406
Copy link
Contributor

Summary

  • Fix: SelectionChanged event is now raised when a bound collection is cleared (or reset) and the control had a selection
  • Root cause: InternalSelectionModel.OnSourceReset called SyncFromSelectedItems() which created an Operation after SelectionModel.OnSourceReset() had already reset _selectedIndex to -1 — the Operation saw no change and never fired SelectionChanged
  • Approach: Snapshot _writableSelectedItems before sync, diff against post-sync state to find actually-lost items, inject as DeselectedItems on the pending Operation (same pattern as OnSelectionRemoved)

Test plan

  • New test: single-select clear raises SelectionChanged with deselected item in RemovedItems
  • New test: multi-select clear raises SelectionChanged with all deselected items
  • New test: reorder Reset (items preserved) does NOT report spurious deselections
  • All 812 existing selection/control tests pass (SelectionModel, InternalSelectionModel, SelectingItemsControl, ListBox, TreeView)

Fixes #20897

…deselected

When a collection bound to a SelectingItemsControl (e.g. ListBox) was
cleared via NotifyCollectionChangedAction.Reset, the SelectionChanged
event was not raised despite the selection being lost.

The root cause was in InternalSelectionModel.OnSourceReset: the base
SelectionModel.OnSourceReset() directly reset _selectedIndex to -1
before any Operation could capture the old selection state. The
subsequent SyncFromSelectedItems created an Operation that saw no
change (old and new both -1), so CommitOperation never fired
SelectionChanged.

The fix snapshots _writableSelectedItems before sync, diffs against
the post-sync state to find items that were actually lost (not merely
re-selected at a new index after reorder), and injects them as
DeselectedItems on the pending Operation — following the same pattern
used by OnSelectionRemoved for individual item removals.

Fixes AvaloniaUI#20897
@avaloniaui-bot
Copy link

You can test this PR using the following package version. 12.0.999-cibuild0063669-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@MrJul MrJul added bug backport-candidate-11.3.x Consider this PR for backporting to 11.3 branch labels Mar 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-candidate-11.3.x Consider this PR for backporting to 11.3 branch bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ListBox does not raise SelectionChanged event when clearing items with NotifyCollectionChangedAction.Reset

3 participants