private void RectangleSelection_PointerMoved(object sender, PointerRoutedEventArgs e) { if (scrollViewer == null) { return; } var currentPoint = e.GetCurrentPoint(uiElement); var verticalOffset = scrollViewer.VerticalOffset; if (selectionState == SelectionState.Starting) { if (!HasMovedMinimalDelta(originDragPoint.X, originDragPoint.Y - verticalOffset, currentPoint.Position.X, currentPoint.Position.Y)) { return; } // Clear selected items once if the pointer is pressed and moved selectionStrategy.StartSelection(); OnSelectionStarted(); selectionState = SelectionState.Active; } if (currentPoint.Properties.IsLeftButtonPressed) { var originDragPointShifted = new Point(originDragPoint.X, originDragPoint.Y - verticalOffset); // Initial drag point relative to the topleft corner base.DrawRectangle(currentPoint, originDragPointShifted, uiElement); // Selected area considering scrolled offset 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))); foreach (var item in itemsPosition.ToList()) { try { if (rect.IntersectsWith(item.Value)) { selectionStrategy.HandleIntersectionWithItem(item.Key); } else { selectionStrategy.HandleNoIntersectionWithItem(item.Key); } } catch (ArgumentException) { // Item is not present in the ItemsSource itemsPosition.Remove(item); } } if (currentPoint.Position.Y > uiElement.ActualHeight - 20) { // Scroll down the list if pointer is at the bottom var scrollIncrement = Math.Min(currentPoint.Position.Y - (uiElement.ActualHeight - 20), 40); scrollViewer.ChangeView(null, verticalOffset + scrollIncrement, null, false); } else if (currentPoint.Position.Y < 20) { // Scroll up the list if pointer is at the top var scrollIncrement = Math.Min(20 - currentPoint.Position.Y, 40); scrollViewer.ChangeView(null, verticalOffset - scrollIncrement, null, false); } } }