public static async Task ScrollToItem(this ScrollViewer scrollViewer, SelectorItem selectorItem)
        {
            // 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(-scrollViewer.ViewportWidth / 2.0, 0));

            // touch selection works without animation so the workaround is needed
            await Task.Delay(1);

            scrollViewer.ChangeView(position.X, position.Y, null);
        }
Esempio n. 2
0
        private static async Task ScrollIntoView(
            ListViewBase listViewBase,
            ScrollViewer scrollViewer,
            SelectorItem selectorItem,
            bool isVirtualizing,
            double previousXOffset,
            double previousYOffset,
            ItemPosition itemPosition = ItemPosition.Default,
            bool disableAnimation     = false)
        {
            var transform = selectorItem.TransformToVisual((UIElement)scrollViewer.Content);
            var position  = transform.TransformPoint(new Point(0, 0));

            if (isVirtualizing)
            {
                var tcs = new TaskCompletionSource <object>();

                EventHandler <ScrollViewerViewChangedEventArgs> viewChanged = (s, e) => tcs.TrySetResult(null);
                try
                {
                    scrollViewer.ViewChanged += viewChanged;
                    scrollViewer.ChangeView(previousXOffset, previousYOffset, null, true);
                    await tcs.Task;
                }
                finally
                {
                    scrollViewer.ViewChanged -= viewChanged;
                }
            }

            var listViewBaseWidth  = listViewBase.ActualWidth;
            var selectorItemWidth  = selectorItem.ActualWidth;
            var listViewBaseHeight = listViewBase.ActualHeight;
            var selectorItemHeight = selectorItem.ActualHeight;

            previousXOffset = scrollViewer.HorizontalOffset;
            previousYOffset = scrollViewer.VerticalOffset;

            if (itemPosition == ItemPosition.Left)
            {
                scrollViewer.ChangeView(position.X, previousYOffset, null, disableAnimation);
            }
            else if (itemPosition == ItemPosition.Top)
            {
                scrollViewer.ChangeView(previousXOffset, position.Y, null, disableAnimation);
            }
            else if (itemPosition == ItemPosition.Center)
            {
                var CentreX        = (listViewBaseWidth - selectorItemWidth) / 2.0;
                var CentreY        = (listViewBaseHeight - selectorItemHeight) / 2.0;
                var finalXPosition = position.X - CentreX;
                var finalYPosition = position.Y - CentreY;
                scrollViewer.ChangeView(finalXPosition, finalYPosition, null, disableAnimation);
            }
            else if (itemPosition == ItemPosition.Right)
            {
                var finalXPosition = position.X - listViewBaseWidth + selectorItemWidth;
                scrollViewer.ChangeView(finalXPosition, previousYOffset, null, disableAnimation);
            }
            else if (itemPosition == ItemPosition.Bottom)
            {
                var finalYPosition = position.Y - listViewBaseHeight + selectorItemHeight;
                scrollViewer.ChangeView(previousXOffset, finalYPosition, null, disableAnimation);
            }
            else if (itemPosition == ItemPosition.Default)
            {
                var bottomXPosition = position.X - listViewBaseWidth + selectorItemWidth;
                var finalXPosition  = position.X;

                if (previousXOffset < position.X && previousXOffset > bottomXPosition)
                {
                    finalXPosition = previousXOffset;
                }
                else if (Math.Abs(previousXOffset - bottomXPosition) < Math.Abs(previousXOffset - position.X))
                {
                    finalXPosition = bottomXPosition;
                }

                var rightYPosition = position.Y - listViewBaseHeight + selectorItemHeight;
                var finalYPosition = position.Y;

                if (previousYOffset < position.Y && previousYOffset > rightYPosition)
                {
                    finalYPosition = previousYOffset;
                }
                else if (Math.Abs(previousYOffset - rightYPosition) < Math.Abs(previousYOffset - position.Y))
                {
                    finalYPosition = rightYPosition;
                }

                scrollViewer.ChangeView(finalXPosition, finalYPosition, null, disableAnimation);
            }
        }