2
2
using System ;
3
3
using System . Collections . Generic ;
4
4
using System . Linq ;
5
+ using Microsoft . Toolkit . Uwp . UI ;
5
6
using Windows . Foundation ;
6
7
using Windows . System ;
7
8
using Windows . UI . Xaml ;
@@ -16,7 +17,7 @@ public class RectangleSelection_ListViewBase : RectangleSelection
16
17
private ListViewBase uiElement ;
17
18
private ScrollViewer scrollViewer ;
18
19
private SelectionChangedEventHandler selectionChanged ;
19
-
20
+ private DispatcherQueueTimer timer = DispatcherQueue . GetForCurrentThread ( ) . CreateTimer ( ) ;
20
21
private Point originDragPoint ;
21
22
private Dictionary < object , System . Drawing . Rectangle > itemsPosition ;
22
23
private List < object > prevSelectedItems ;
@@ -58,19 +59,6 @@ private void RectangleSelection_PointerMoved(object sender, PointerRoutedEventAr
58
59
base . DrawRectangle ( currentPoint , originDragPointShifted , uiElement ) ;
59
60
// Selected area considering scrolled offset
60
61
var rect = new System . Drawing . Rectangle ( ( int ) Canvas . GetLeft ( selectionRectangle ) , ( int ) Math . Min ( originDragPoint . Y , currentPoint . Position . Y + verticalOffset ) , ( int ) selectionRectangle . Width , ( int ) Math . Abs ( originDragPoint . Y - ( currentPoint . Position . Y + verticalOffset ) ) ) ;
61
- foreach ( var item in uiElement . Items . ToList ( ) . Except ( itemsPosition . Keys ) )
62
- {
63
- var listViewItem = ( FrameworkElement ) uiElement . ContainerFromItem ( item ) ; // Get ListViewItem
64
- if ( listViewItem == null )
65
- {
66
- continue ; // Element is not loaded (virtualized list)
67
- }
68
-
69
- var gt = listViewItem . TransformToVisual ( uiElement ) ;
70
- var itemStartPoint = gt . TransformPoint ( new Point ( 0 , verticalOffset ) ) ; // Get item position relative to the top of the list (considering scrolled offset)
71
- var itemRect = new System . Drawing . Rectangle ( ( int ) itemStartPoint . X , ( int ) itemStartPoint . Y , ( int ) listViewItem . ActualWidth , ( int ) listViewItem . ActualHeight ) ;
72
- itemsPosition [ item ] = itemRect ;
73
- }
74
62
75
63
foreach ( var item in itemsPosition . ToList ( ) )
76
64
{
@@ -109,9 +97,27 @@ private void RectangleSelection_PointerMoved(object sender, PointerRoutedEventAr
109
97
private void RectangleSelection_PointerPressed ( object sender , PointerRoutedEventArgs e )
110
98
{
111
99
itemsPosition . Clear ( ) ;
100
+
101
+ var verticalOffset = scrollViewer ? . VerticalOffset ?? 0 ;
102
+ foreach ( var item in uiElement . Items . ToList ( ) . Except ( itemsPosition . Keys ) )
103
+ {
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 ;
114
+ }
115
+ scrollViewer . ViewChanged -= ScrollViewer_ViewChanged ;
116
+ scrollViewer . ViewChanged += ScrollViewer_ViewChanged ;
117
+
112
118
originDragPoint = new Point ( e . GetCurrentPoint ( uiElement ) . Position . X , e . GetCurrentPoint ( uiElement ) . Position . Y ) ; // Initial drag point relative to the topleft corner
113
119
prevSelectedItems = uiElement . SelectedItems . Cast < object > ( ) . ToList ( ) ; // Save current selected items
114
- var verticalOffset = scrollViewer ? . VerticalOffset ?? 0 ;
120
+
115
121
originDragPoint . Y += verticalOffset ; // Initial drag point relative to the top of the list (considering scrolled offset)
116
122
if ( ! e . GetCurrentPoint ( uiElement ) . Properties . IsLeftButtonPressed || e . Pointer . PointerDeviceType == Windows . Devices . Input . PointerDeviceType . Touch )
117
123
{
@@ -138,13 +144,41 @@ private void RectangleSelection_PointerPressed(object sender, PointerRoutedEvent
138
144
selectionState = SelectionState . Starting ;
139
145
}
140
146
147
+ private void ScrollViewer_ViewChanged ( object sender , ScrollViewerViewChangedEventArgs e )
148
+ {
149
+ if ( ! e . IsIntermediate )
150
+ {
151
+ timer . Stop ( ) ;
152
+ timer . Debounce ( ( ) =>
153
+ {
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
+ }
163
+
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 ) ) ;
170
+ }
171
+ }
172
+
141
173
private void RectangleSelection_PointerReleased ( object sender , PointerRoutedEventArgs e )
142
174
{
143
175
Canvas . SetLeft ( selectionRectangle , 0 ) ;
144
176
Canvas . SetTop ( selectionRectangle , 0 ) ;
145
177
selectionRectangle . Width = 0 ;
146
178
selectionRectangle . Height = 0 ;
147
179
uiElement . PointerMoved -= RectangleSelection_PointerMoved ;
180
+
181
+ scrollViewer . ViewChanged -= ScrollViewer_ViewChanged ;
148
182
uiElement . ReleasePointerCapture ( e . Pointer ) ;
149
183
if ( selectionChanged != null )
150
184
{
0 commit comments