public async static Task ScrollToItem(this ListViewBase listViewBase, object item) { bool isVirtualizing = default(bool); double previousHorizontalOffset = default(double), previousVerticalOffset = default(double); // get the ScrollViewer withtin the ListView/GridView var scrollViewer = listViewBase?.GetScrollViewer(); // get the SelectorItem to scroll to var selectorItem = listViewBase?.ContainerFromItem(item) as SelectorItem; // when it's null, means virtualization is on and the item hasn't been realized yet if (selectorItem == null && listViewBase != null && scrollViewer != null) { isVirtualizing = true; previousHorizontalOffset = scrollViewer?.HorizontalOffset ?? 0.0; previousVerticalOffset = scrollViewer?.VerticalOffset ?? 0.0; // call task-based ScrollIntoViewAsync to realize the item await listViewBase?.ScrollIntoViewAsync(item); // this time the item shouldn't be null again selectorItem = (SelectorItem)listViewBase?.ContainerFromItem(item); } // calculate the position object in order to know how much to scroll to var transform = selectorItem?.TransformToVisual((UIElement)scrollViewer?.Content); var position = transform?.TransformPoint(new Point(0, 0)) ?? new Point(0, 0); // when virtualized, scroll back to previous position without animation if (isVirtualizing) { await scrollViewer?.ChangeViewAsync(previousHorizontalOffset, previousVerticalOffset, true); } // scroll to desired position with animation! scrollViewer?.ChangeView(position.X, position.Y - scrollViewer?.ActualHeight / 2, null); }
public async static Task ScrollToItem2(this ListViewBase listViewBase, object item, VerticalAlignment alignment, bool highlight, double?pixel = null) { var scrollViewer = listViewBase.GetScrollViewer(); if (scrollViewer == null) { return; } //listViewBase.SelectionMode = ListViewSelectionMode.Single; //listViewBase.SelectedItem = item; var selectorItem = listViewBase.ContainerFromItem(item) as SelectorItem; if (selectorItem == null) { // call task-based ScrollIntoViewAsync to realize the item await listViewBase.ScrollIntoViewAsync(item); // this time the item shouldn't be null again selectorItem = (SelectorItem)listViewBase.ContainerFromItem(item); } if (selectorItem == null) { return; } // calculate the position object in order to know how much to scroll to var transform = selectorItem.TransformToVisual((UIElement)scrollViewer.Content); var position = transform.TransformPoint(new Point(0, 0)); if (alignment == VerticalAlignment.Top) { if (pixel is double adjust) { position.Y -= adjust; } } else if (alignment == VerticalAlignment.Center) { position.Y -= (listViewBase.ActualHeight - selectorItem.ActualHeight) / 2d; } else if (alignment == VerticalAlignment.Bottom) { position.Y -= listViewBase.ActualHeight - selectorItem.ActualHeight; if (pixel is double adjust) { position.Y += adjust; } } // scroll to desired position with animation! scrollViewer.ChangeView(position.X, position.Y, null, alignment != VerticalAlignment.Center); if (highlight) { var bubble = selectorItem.Descendants <MessageBubble>().FirstOrDefault() as MessageBubble; if (bubble == null) { return; } bubble.Highlight(); } }
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 uiElement.Items.ToList().Except(itemsPosition.Keys)) { var listViewItem = (FrameworkElement)uiElement.ContainerFromItem(item); // Get ListViewItem if (listViewItem == null) { continue; // Element is not loaded (virtualized list) } var gt = listViewItem.TransformToVisual(uiElement); var itemStartPoint = gt.TransformPoint(new Point(0, verticalOffset)); // Get item position relative to the top of the list (considering scrolled offset) var itemRect = new System.Drawing.Rectangle((int)itemStartPoint.X, (int)itemStartPoint.Y, (int)listViewItem.ActualWidth, (int)listViewItem.ActualHeight); itemsPosition[item] = itemRect; } 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); } } }
public async static Task ScrollToItem(this ListViewBase listViewBase, object item, SnapPointsAlignment alignment, bool highlight, double?pixel = null) { // get the ScrollViewer withtin the ListView/GridView var scrollViewer = listViewBase.GetScrollViewer(); // get the SelectorItem to scroll to var selectorItem = listViewBase.ContainerFromItem(item) as SelectorItem; // when it's null, means virtualization is on and the item hasn't been realized yet if (selectorItem == null) { // call task-based ScrollIntoViewAsync to realize the item await listViewBase.ScrollIntoViewAsync(item); // this time the item shouldn't be null again selectorItem = (SelectorItem)listViewBase.ContainerFromItem(item); } if (selectorItem == null) { return; } // calculate the position object in order to know how much to scroll to var transform = selectorItem.TransformToVisual((UIElement)scrollViewer.Content); var position = transform.TransformPoint(new Point(0, 0)); if (alignment == SnapPointsAlignment.Near) { if (pixel is double adjust) { position.Y -= adjust; } } else if (alignment == SnapPointsAlignment.Center) { position.Y -= (listViewBase.ActualHeight - selectorItem.ActualHeight) / 2d; } else if (alignment == SnapPointsAlignment.Far) { position.Y -= listViewBase.ActualHeight - selectorItem.ActualHeight; if (pixel is double adjust) { position.Y += adjust; } } // scroll to desired position with animation! scrollViewer.ChangeView(position.X, position.Y, null, alignment != SnapPointsAlignment.Center); if (highlight) { var bubble = selectorItem.Descendants <MessageBubble>().FirstOrDefault() as MessageBubble; if (bubble == null) { return; } bubble.Highlight(); } }
private void View_PointerMoved(object sender, PointerRoutedEventArgs e) { if (IsEnabled && e.Pointer.PointerDeviceType == PointerDeviceType.Mouse && e.GetCurrentPoint(View).Properties.IsLeftButtonPressed) { if (Interlocked.Exchange(ref Locker, 1) == 0) { try { Point RelativeEndPoint = e.GetCurrentPoint(View).Position; SrcollIfNeed(RelativeEndPoint); Point AbsEndPoint = new Point(RelativeEndPoint.X + InnerScrollView.HorizontalOffset, RelativeEndPoint.Y + InnerScrollView.VerticalOffset); Point RelativeStartPoint = new Point(AbsStartPoint.X - InnerScrollView.HorizontalOffset, AbsStartPoint.Y - InnerScrollView.VerticalOffset); DrawRectangleInCanvas(RelativeStartPoint, RelativeEndPoint); if (Math.Abs(RelativeStartPoint.X - RelativeEndPoint.X) >= 20 && Math.Abs(RelativeStartPoint.Y - RelativeEndPoint.Y) >= 20) { List <FileSystemStorageItemBase> VisibleList = new List <FileSystemStorageItemBase>(); if (View is ListView) { ItemsStackPanel VirtualPanel = View.ItemsPanelRoot as ItemsStackPanel; for (int i = VirtualPanel.FirstVisibleIndex; i <= VirtualPanel.LastVisibleIndex; i++) { VisibleList.Add(View.Items[i] as FileSystemStorageItemBase); } } else { ItemsWrapGrid VirtualPanel = View.ItemsPanelRoot as ItemsWrapGrid; for (int i = VirtualPanel.FirstVisibleIndex; i <= VirtualPanel.LastVisibleIndex; i++) { VisibleList.Add(View.Items[i] as FileSystemStorageItemBase); } } foreach (FileSystemStorageItemBase Item in VisibleList.Except(AbsItemLocationRecord.Select((Rec) => Rec.Key))) { if (View.ContainerFromItem(Item) is SelectorItem Selector) { AbsItemLocationRecord.Add(new KeyValuePair <FileSystemStorageItemBase, Rect>(Item, Selector.TransformToVisual(View).TransformBounds(new Rect(InnerScrollView.HorizontalOffset, InnerScrollView.VerticalOffset, Selector.ActualWidth, Selector.ActualHeight)))); } } Rect AbsBoxSelectionRect = new Rect(Math.Min(AbsStartPoint.X, AbsEndPoint.X), Math.Min(AbsStartPoint.Y, AbsEndPoint.Y), Math.Abs(AbsStartPoint.X - AbsEndPoint.X), Math.Abs(AbsStartPoint.Y - AbsEndPoint.Y)); foreach (KeyValuePair <FileSystemStorageItemBase, Rect> Pair in AbsItemLocationRecord) { Rect Intersect = RectHelper.Intersect(AbsBoxSelectionRect, Pair.Value); if (!Intersect.IsEmpty && Intersect.Width > 0 && Intersect.Height > 0) { if (!View.SelectedItems.Contains(Pair.Key)) { View.SelectedItems.Add(Pair.Key); } } else { View.SelectedItems.Remove(Pair.Key); } } } } catch (Exception ex) { LogTracer.Log(ex); } finally { _ = Interlocked.Exchange(ref Locker, 0); } } } }
private void View_PointerMoved(object sender, PointerRoutedEventArgs e) { if (AllowProcess && e.Pointer.PointerDeviceType == PointerDeviceType.Mouse && e.GetCurrentPoint(View).Properties.IsLeftButtonPressed) { if (Interlocked.Exchange(ref Locker, 1) == 0) { try { Point RelativeEndPoint = e.GetCurrentPoint(View).Position; SrcollIfNeed(RelativeEndPoint); Point RelativeStartPoint = new Point(AbsStartPoint.X - InnerScrollView.HorizontalOffset, AbsStartPoint.Y - InnerScrollView.VerticalOffset); DrawRectangleInCanvas(RelativeStartPoint, RelativeEndPoint); GeneralTransform AbsToWindowTransform = View.TransformToVisual(Window.Current.Content); Rect SelectedRect = new Rect(RelativeStartPoint, RelativeEndPoint); if (SelectedRect.Width >= 20 && SelectedRect.Height >= 20) { IEnumerable <FileSystemStorageItemBase> SelectedList = VisualTreeHelper.FindElementsInHostCoordinates(AbsToWindowTransform.TransformBounds(SelectedRect), View).OfType <SelectorItem>().Select((Item) => Item.Content as FileSystemStorageItemBase); foreach (FileSystemStorageItemBase Item in View.SelectedItems.OfType <FileSystemStorageItemBase>().Except(SelectedList).Where((Item) => (View.ContainerFromItem(Item) as SelectorItem).IsVisibleOnContainer(View))) { View.SelectedItems.Remove(Item); } foreach (FileSystemStorageItemBase Item in SelectedList.Except(View.SelectedItems.OfType <FileSystemStorageItemBase>())) { View.SelectedItems.Add(Item); } } } catch (Exception ex) { LogTracer.Log(ex); } finally { _ = Interlocked.Exchange(ref Locker, 0); } } } }