@@ -17,7 +17,7 @@ public class RectangleSelection_ListViewBase : RectangleSelection
17
17
private ListViewBase uiElement ;
18
18
private ScrollViewer scrollViewer ;
19
19
private SelectionChangedEventHandler selectionChanged ;
20
- private DispatcherQueueTimer timer = DispatcherQueue . GetForCurrentThread ( ) . CreateTimer ( ) ;
20
+ private DispatcherQueueTimer timer ;
21
21
private Point originDragPoint ;
22
22
private Dictionary < object , System . Drawing . Rectangle > itemsPosition ;
23
23
private List < object > prevSelectedItems ;
@@ -29,6 +29,7 @@ public RectangleSelection_ListViewBase(ListViewBase uiElement, Rectangle selecti
29
29
this . selectionRectangle = selectionRectangle ;
30
30
this . selectionChanged = selectionChanged ;
31
31
itemsPosition = new Dictionary < object , System . Drawing . Rectangle > ( ) ;
32
+ timer = DispatcherQueue . GetForCurrentThread ( ) . CreateTimer ( ) ;
32
33
InitEvents ( null , null ) ;
33
34
}
34
35
@@ -96,35 +97,29 @@ private void RectangleSelection_PointerMoved(object sender, PointerRoutedEventAr
96
97
97
98
private void RectangleSelection_PointerPressed ( object sender , PointerRoutedEventArgs e )
98
99
{
99
- itemsPosition . Clear ( ) ;
100
-
101
- var verticalOffset = scrollViewer ? . VerticalOffset ?? 0 ;
102
- foreach ( var item in uiElement . Items . ToList ( ) . Except ( itemsPosition . Keys ) )
100
+ if ( scrollViewer == null )
103
101
{
104
- var listViewItem = ( FrameworkElement ) uiElement . ContainerFromItem ( item ) ; // Get ListViewItem
105
- if ( listViewItem == null )
106
- {
107
- continue ; // Element is not loaded (virtualized list)
108
- }
109
-
110
- var gt = listViewItem . TransformToVisual ( uiElement ) ;
111
- var itemStartPoint = gt . TransformPoint ( new Point ( 0 , verticalOffset ) ) ; // Get item position relative to the top of the list (considering scrolled offset)
112
- var itemRect = new System . Drawing . Rectangle ( ( int ) itemStartPoint . X , ( int ) itemStartPoint . Y , ( int ) listViewItem . ActualWidth , ( int ) listViewItem . ActualHeight ) ;
113
- itemsPosition [ item ] = itemRect ;
102
+ return ;
114
103
}
104
+
105
+ itemsPosition . Clear ( ) ;
106
+
115
107
scrollViewer . ViewChanged -= ScrollViewer_ViewChanged ;
116
108
scrollViewer . ViewChanged += ScrollViewer_ViewChanged ;
117
109
118
110
originDragPoint = new Point ( e . GetCurrentPoint ( uiElement ) . Position . X , e . GetCurrentPoint ( uiElement ) . Position . Y ) ; // Initial drag point relative to the topleft corner
119
111
prevSelectedItems = uiElement . SelectedItems . Cast < object > ( ) . ToList ( ) ; // Save current selected items
120
112
113
+ var verticalOffset = scrollViewer . VerticalOffset ;
121
114
originDragPoint . Y += verticalOffset ; // Initial drag point relative to the top of the list (considering scrolled offset)
122
115
if ( ! e . GetCurrentPoint ( uiElement ) . Properties . IsLeftButtonPressed || e . Pointer . PointerDeviceType == Windows . Devices . Input . PointerDeviceType . Touch )
123
116
{
124
117
// Trigger only on left click, do not trigger with touch
125
118
return ;
126
119
}
127
120
121
+ FetchItemsPosition ( ) ;
122
+
128
123
selectionStrategy = e . KeyModifiers . HasFlag ( VirtualKeyModifiers . Control ) ?
129
124
new InvertPreviousItemSelectionStrategy ( uiElement . SelectedItems , prevSelectedItems ) :
130
125
e . KeyModifiers . HasFlag ( VirtualKeyModifiers . Shift ) ?
@@ -144,29 +139,29 @@ private void RectangleSelection_PointerPressed(object sender, PointerRoutedEvent
144
139
selectionState = SelectionState . Starting ;
145
140
}
146
141
147
- private void ScrollViewer_ViewChanged ( object sender , ScrollViewerViewChangedEventArgs e )
142
+ private void FetchItemsPosition ( )
148
143
{
149
- if ( ! e . IsIntermediate )
144
+ var verticalOffset = scrollViewer . VerticalOffset ;
145
+ foreach ( var item in uiElement . Items . ToList ( ) . Except ( itemsPosition . Keys ) )
150
146
{
151
- timer . Stop ( ) ;
152
- timer . Debounce ( ( ) =>
147
+ var listViewItem = ( FrameworkElement ) uiElement . ContainerFromItem ( item ) ; // Get ListViewItem
148
+ if ( listViewItem == null )
153
149
{
154
- var verticalOffset = scrollViewer ? . VerticalOffset ?? 0 ;
155
-
156
- foreach ( var item in uiElement . Items . ToList ( ) . Except ( itemsPosition . Keys ) )
157
- {
158
- var listViewItem = ( FrameworkElement ) uiElement . ContainerFromItem ( item ) ; // Get ListViewItem
159
- if ( listViewItem == null )
160
- {
161
- continue ; // Element is not loaded (virtualized list)
162
- }
150
+ continue ; // Element is not loaded (virtualized list)
151
+ }
163
152
164
- var gt = listViewItem . TransformToVisual ( uiElement ) ;
165
- var itemStartPoint = gt . TransformPoint ( new Point ( 0 , verticalOffset ) ) ; // Get item position relative to the top of the list (considering scrolled offset)
166
- var itemRect = new System . Drawing . Rectangle ( ( int ) itemStartPoint . X , ( int ) itemStartPoint . Y , ( int ) listViewItem . ActualWidth , ( int ) listViewItem . ActualHeight ) ;
167
- itemsPosition [ item ] = itemRect ;
168
- }
169
- } , TimeSpan . FromSeconds ( 1 ) ) ;
153
+ var gt = listViewItem . TransformToVisual ( uiElement ) ;
154
+ var itemStartPoint = gt . TransformPoint ( new Point ( 0 , verticalOffset ) ) ; // Get item position relative to the top of the list (considering scrolled offset)
155
+ var itemRect = new System . Drawing . Rectangle ( ( int ) itemStartPoint . X , ( int ) itemStartPoint . Y , ( int ) listViewItem . ActualWidth , ( int ) listViewItem . ActualHeight ) ;
156
+ itemsPosition [ item ] = itemRect ;
157
+ }
158
+ }
159
+
160
+ private void ScrollViewer_ViewChanged ( object sender , ScrollViewerViewChangedEventArgs e )
161
+ {
162
+ if ( ! timer . IsRunning )
163
+ {
164
+ timer . Debounce ( FetchItemsPosition , TimeSpan . FromMilliseconds ( 1000 ) ) ;
170
165
}
171
166
}
172
167
0 commit comments