@@ -19,6 +19,10 @@ public sealed class RectangleSelection_ListViewBase : RectangleSelection
1919 private ScrollViewer scrollViewer ;
2020 private SelectionChangedEventHandler selectionChanged ;
2121 private DispatcherQueueTimer timer ;
22+ private DispatcherQueueTimer selectionUpdateTimer ;
23+ private List < object > ? pendingSelectedItems ;
24+ private List < object > ? pendingRemovedItems ;
25+ private bool isSelectionUpdatePending ;
2226 private Point originDragPoint ;
2327 private Dictionary < object , System . Drawing . Rectangle > itemsPosition ;
2428 private List < object > prevSelectedItems ;
@@ -32,9 +36,23 @@ public RectangleSelection_ListViewBase(ListViewBase uiElement, Rectangle selecti
3236 this . selectionChanged = selectionChanged ;
3337 itemsPosition = [ ] ;
3438 timer = DispatcherQueue . GetForCurrentThread ( ) . CreateTimer ( ) ;
39+ selectionUpdateTimer = DispatcherQueue . GetForCurrentThread ( ) . CreateTimer ( ) ;
40+ selectionUpdateTimer . Interval = TimeSpan . FromMilliseconds ( 8 ) ;
41+ selectionUpdateTimer . Tick += SelectionUpdateTimer_Tick ;
3542 InitEvents ( null , null ) ;
3643 }
3744
45+ private void SelectionUpdateTimer_Tick ( object ? sender , object e )
46+ {
47+ selectionUpdateTimer . Stop ( ) ;
48+ if ( isSelectionUpdatePending && pendingSelectedItems is not null && selectionChanged is not null )
49+ {
50+ selectionChanged ( this , new SelectionChangedEventArgs ( pendingRemovedItems ?? [ ] , pendingSelectedItems ) ) ;
51+ isSelectionUpdatePending = false ;
52+ pendingRemovedItems = null ;
53+ }
54+ }
55+
3856 private void RectangleSelection_PointerMoved ( object sender , PointerRoutedEventArgs e )
3957 {
4058 if ( scrollViewer is null )
@@ -102,9 +120,14 @@ private void RectangleSelection_PointerMoved(object sender, PointerRoutedEventAr
102120 var currentSelectedItemsDrag = uiElement . SelectedItems . Cast < object > ( ) . ToList ( ) ;
103121 if ( prevSelectedItemsDrag is null || ! prevSelectedItemsDrag . SequenceEqual ( currentSelectedItemsDrag ) )
104122 {
105- // Trigger SelectionChanged event if the selection has changed
106123 var removedItems = selectedItemsBeforeChange . Except ( currentSelectedItemsDrag ) . ToList ( ) ;
107- selectionChanged ( sender , new SelectionChangedEventArgs ( removedItems , currentSelectedItemsDrag ) ) ;
124+ pendingSelectedItems = currentSelectedItemsDrag ;
125+ pendingRemovedItems = pendingRemovedItems is null
126+ ? removedItems
127+ : pendingRemovedItems . Union ( removedItems ) . ToList ( ) ;
128+ isSelectionUpdatePending = true ;
129+ selectionUpdateTimer . Stop ( ) ;
130+ selectionUpdateTimer . Start ( ) ;
108131 prevSelectedItemsDrag = currentSelectedItemsDrag ;
109132 }
110133 }
@@ -192,6 +215,17 @@ private void RectangleSelection_PointerReleased(object sender, PointerRoutedEven
192215
193216 scrollViewer . ViewChanged -= ScrollViewer_ViewChanged ;
194217 uiElement . ReleasePointerCapture ( e . Pointer ) ;
218+
219+ if ( selectionUpdateTimer . IsRunning )
220+ {
221+ selectionUpdateTimer . Stop ( ) ;
222+ if ( isSelectionUpdatePending && pendingSelectedItems is not null && selectionChanged is not null )
223+ {
224+ selectionChanged ( this , new SelectionChangedEventArgs ( pendingRemovedItems ?? [ ] , pendingSelectedItems ) ) ;
225+ isSelectionUpdatePending = false ;
226+ }
227+ }
228+
195229 if ( selectionChanged is not null )
196230 {
197231 // Restore and trigger SelectionChanged event
0 commit comments