Beispiel #1
0
        void ScrollTo(object group, object item, ScrollToPosition toPosition, bool shouldAnimate)
        {
            //var viewer = Control.FindVisualChild<ScrollViewer>();
            //if (viewer == null)
            //{
            //	RoutedEventHandler loadedHandler = null;
            //	loadedHandler = (o, e) =>
            //	{
            //		Control.Loaded -= loadedHandler;
            //		Device.BeginInvokeOnMainThread(() => { ScrollTo(group, item, toPosition, shouldAnimate); });
            //	};
            //	Control.Loaded += loadedHandler;
            //	return;
            //}
            //var templatedItems = TemplatedItemsView.TemplatedItems;
            //Tuple<int, int> location = templatedItems.GetGroupAndIndexOfItem(group, item);
            //if (location.Item1 == -1 || location.Item2 == -1)
            //	return;

            //var t = templatedItems.GetGroup(location.Item1).ToArray();
            //var c = t[location.Item2];

            //Device.BeginInvokeOnMainThread(() =>
            //{
            //	ScrollToPositionInView(Control, viewer, c, toPosition, shouldAnimate);
            //});
        }
        private void ScrollTo_Clicked(object sender, EventArgs e)
        {
            VirtualizedItemsControl.ScrollToAsync(source[500], this.nextScrollToPosition, true);

            var previousScrollToPosition = this.nextScrollToPosition;

            switch (this.nextScrollToPosition)
            {
            case ScrollToPosition.MakeVisible:
                this.nextScrollToPosition = ScrollToPosition.Start;
                break;

            case ScrollToPosition.Start:
                this.nextScrollToPosition = ScrollToPosition.Center;
                break;

            case ScrollToPosition.Center:
                this.nextScrollToPosition = ScrollToPosition.End;
                break;

            case ScrollToPosition.End:
                this.nextScrollToPosition = ScrollToPosition.MakeVisible;
                break;

            default:
                break;
            }

            SummaryLabel.Text = $"Scroll to element at index 500 with scroll position : {previousScrollToPosition} (new scroll position wil be {this.nextScrollToPosition})";
        }
Beispiel #3
0
 /// <summary>
 /// Scrolls to.
 /// </summary>
 /// <param name="sourceItem">Source item.</param>
 /// <param name="sourceGroup">Source group.</param>
 /// <param name="scrollToPosition">Scroll to position.</param>
 /// <param name="animated">If set to <c>true</c> animated.</param>
 public void ScrollTo(object sourceItem, object sourceGroup, ScrollToPosition scrollToPosition, bool animated = true)
 {
     if (_refView.TryGetTarget(out var collection))
     {
         collection.ScrollTo(sourceItem, sourceGroup, scrollToPosition, animated);
     }
 }
        async Task JumpTo(ListViewBase list, object targetItem, ScrollToPosition scrollToPosition)
        {
            var tcs = new TaskCompletionSource <object>();

            void ViewChanged(object s, ScrollViewerViewChangedEventArgs e) => tcs.TrySetResult(null);

            var scrollViewer = list.GetFirstDescendant <ScrollViewer>();

            try
            {
                scrollViewer.ViewChanged += ViewChanged;

                if (scrollToPosition == ScrollToPosition.Start)
                {
                    list.ScrollIntoView(targetItem, ScrollIntoViewAlignment.Leading);
                }
                else if (scrollToPosition == ScrollToPosition.MakeVisible)
                {
                    list.ScrollIntoView(targetItem, ScrollIntoViewAlignment.Default);
                }
                else
                {
                    // Center and End are going to be more complicated.
                }

                await tcs.Task;
            }
            finally
            {
                scrollViewer.ViewChanged -= ViewChanged;
            }
        }
Beispiel #5
0
        void AdjustHorizontalScroll(int index, ScrollToPosition scrollToPosition)
        {
            _pendingScrollAdjustment = null;

            var viewRect = GetViewRect(index);

            if (viewRect == null)
            {
                return;
            }

            var offset = 0;

            var rvRect = new ARect();

            _recyclerView.GetGlobalVisibleRect(rvRect);

            if (scrollToPosition == ScrollToPosition.Center)
            {
                offset = viewRect.CenterX() - rvRect.CenterX();
            }
            else if (scrollToPosition == ScrollToPosition.End)
            {
                offset = viewRect.Right - rvRect.Right;
            }

            _recyclerView.ScrollBy(offset, 0);
        }
Beispiel #6
0
 internal ScrollToRequestedEventArgs(Element element, ScrollToPosition position, bool shouldAnimate)
 {
     Element       = element;
     Position      = position;
     ShouldAnimate = shouldAnimate;
     Mode          = ScrollToMode.Element;
 }
Beispiel #7
0
        void ScrollTo(object group, object item, ScrollToPosition toPosition, bool shouldAnimate)
        {
            var viewer = _listview.FindVisualChild <ScrollViewer>();

            if (viewer == null)
            {
                RoutedEventHandler loadedHandler = null;
                loadedHandler = (o, e) =>
                {
                    _listview.Loaded -= loadedHandler;
                    Device.BeginInvokeOnMainThread(() => { ScrollTo(group, item, toPosition, shouldAnimate); });
                };
                _listview.Loaded += loadedHandler;
                return;
            }
            var templatedItems        = TemplatedItemsView.TemplatedItems;
            Tuple <int, int> location = templatedItems.GetGroupAndIndexOfItem(group, item);

            if (location.Item1 == -1 || location.Item2 == -1)
            {
                return;
            }

            var t = templatedItems.GetGroup(location.Item1).ToArray();
            var c = t[location.Item2];

            Device.BeginInvokeOnMainThread(() =>
            {
                ScrollToPositionInView(_listview, viewer, c, toPosition, shouldAnimate);
            });
        }
		internal ScrollToRequestedEventArgs(object item, ScrollToPosition position, bool shouldAnimate)
		{
			Item = item;
			Position = position;
			ShouldAnimate = shouldAnimate;
			//Mode = ScrollToMode.Item;
		}
Beispiel #9
0
        /// <summary>
        /// Return a point where the child at <paramref name="index"/> should appear
        /// </summary>
        /// <param name="index">Index of child in collection</param>
        /// <param name="scrollToPosition">Position of child after scrolling</param>
        /// <returns>The top left point to scroll to</returns>
        protected virtual Point GetChildPositionForScroll(int index, ScrollToPosition scrollToPosition)
        {
            var y = rowHeight * index;
            var adaptedScrollToPosition = scrollToPosition;

            if (adaptedScrollToPosition == ScrollToPosition.MakeVisible)
            {
                if (y < Viewport.Y)
                {
                    adaptedScrollToPosition = ScrollToPosition.Start;
                }
                else if (y + rowHeight > Viewport.Y + Viewport.Height)
                {
                    adaptedScrollToPosition = ScrollToPosition.End;
                }
                else
                {
                    y = Viewport.Y;
                }
            }

            switch (adaptedScrollToPosition)
            {
            case ScrollToPosition.Center:
                y -= (Viewport.Height / 2d) - (rowHeight / 2d);
                break;

            case ScrollToPosition.End:
                y -= Viewport.Height - rowHeight;
                break;
            }

            return(new Point(0, y));
        }
		internal ScrollToRequestedEventArgs(Element element, ScrollToPosition position, bool shouldAnimate)
		{
			Element = element;
			Position = position;
			ShouldAnimate = shouldAnimate;
			Mode = ScrollToMode.Element;
		}
Beispiel #11
0
 internal ScrollToRequestedEventArgs(object item, ScrollToPosition position, bool shouldAnimate)
 {
     Item          = item;
     Position      = position;
     ShouldAnimate = shouldAnimate;
     //Mode = ScrollToMode.Item;
 }
Beispiel #12
0
 public static void ScrollIfExist <T>(this ListView listView, T itemToScroll, ScrollToPosition type)
 {
     if (itemToScroll != null)
     {
         listView.ScrollTo(itemToScroll, type, false);
     }
 }
Beispiel #13
0
        void AdjustVerticalScroll(int index, ScrollToPosition scrollToPosition)
        {
            _pendingScrollAdjustment = null;

            var viewRect = GetViewRect(index);

            if (viewRect == null)
            {
                return;
            }

            var offset = 0;

            var rvRect = new ARect();

            _recyclerView.GetGlobalVisibleRect(rvRect);

            if (scrollToPosition == ScrollToPosition.Center)
            {
                offset = viewRect.CenterY() - rvRect.CenterY();
            }
            else if (scrollToPosition == ScrollToPosition.End)
            {
                offset = viewRect.Bottom - rvRect.Bottom;
            }

            _recyclerView.ScrollBy(0, offset);
        }
		internal ScrollToRequestedEventArgs(object item, object group, ScrollToPosition position, bool shouldAnimate)
		{
			Item = item;
			Group = group;
			Position = position;
			ShouldAnimate = shouldAnimate;
			//Mode = ScrollToMode.GroupAndIem;
		}
 public static void ScrollToWithDelay(ListView lv, object item, ScrollToPosition position, bool animated = true)
 {
     Device.StartTimer(TimeSpan.FromMilliseconds(50), () =>
     {
         lv.ScrollTo(item, position, animated);
         return(false);
     });
 }
Beispiel #16
0
 internal ScrollToRequestedEventArgs(object item, object group, ScrollToPosition position, bool shouldAnimate)
 {
     Item          = item;
     Group         = group;
     Position      = position;
     ShouldAnimate = shouldAnimate;
     //Mode = ScrollToMode.GroupAndIem;
 }
Beispiel #17
0
 private void ScrollToMessage(Message message, ScrollToPosition position, bool animated = false)
 {
     if (message != null)
     {
         ScrollTo(message, position, animated);
     }
     _topmostItemIndex = null;
 }
Beispiel #18
0
        public void JumpScrollToPosition(int index, ScrollToPosition scrollToPosition, bool uniformSize = false)
        {
            if (scrollToPosition == ScrollToPosition.MakeVisible)
            {
                // MakeVisible is the default behavior, so we don't need to do anything special
                _recyclerView.ScrollToPosition(index);
                return;
            }

            if (!(_recyclerView.GetLayoutManager() is LinearLayoutManager linearLayoutManager))
            {
                // We don't have the ScrollToPositionWithOffset method available, so we don't have a way to
                // handle the Forms ScrollToPosition; just default back to the MakeVisible behavior
                _recyclerView.ScrollToPosition(index);
                return;
            }

            // If ScrollToPosition is Start, then we can just use an offset of 0 and we're fine
            // (Though that may change in RTL situations or if we're stacking from the end)
            if (scrollToPosition == Microsoft.Maui.Controls.ScrollToPosition.Start)
            {
                linearLayoutManager.ScrollToPositionWithOffset(index, 0);
                return;
            }

            // For handling End or Center, things get more complicated because we need to know the size of
            // the View we're targeting.

            // If we're using ItemSizingStrategy MeasureFirstItem, we can use any item size as a guide to figure
            // out the offset

            // TODO hartez 2018/10/03 14:00:32 Handle the MeasureFirstItem case to determine the offset and call
            // `linearLayoutManager.ScrollToPositionWithOffset(index, offset);` here
            // Use the uniformSize parameter and pass that in based on ItemsView.ItemSizingStrategy

            // If we don't already know the size of the item, things get more complicated

            // The item may not actually exist; it may have never been realized, or it may have been recycled
            // So we need to get it on screen using ScrollToPosition, then once it's on screen we can use the
            // width/height to make adjustments for Center/End.

            // ScrollToPosition queues up the scroll operation. It doesn't do it immediately; it requests a layout
            // After that layout is finished, the view will be available for measurement and then we can adjust
            // the scroll to get it into the right place

            // Set up our pending adjustment
            if (linearLayoutManager.CanScrollVertically())
            {
                _pendingScrollAdjustment = () => AdjustVerticalScroll(index, scrollToPosition);
            }
            else
            {
                _pendingScrollAdjustment = () => AdjustHorizontalScroll(index, scrollToPosition);
            }

            // Kick off the Scroll to get the item into view; once it's in view, the pending adjustment will kick in
            _recyclerView.ScrollToPosition(index);
        }
        /// <summary>
        /// Scrolls the list to a specified cell.
        /// </summary>
        /// <remarks>
        /// Different scrolling behaviors are also possible. The element may be positioned in the center,
        /// top or bottom of the visible part of the list depending on the value of the <c>position</c> parameter.
        /// </remarks>
        /// <param name="cell">Cell which will be displayed after scrolling .</param>
        /// <param name="position">This will defines scroll to behavior based on ScrollToPosition values.</param>
        /// <param name="animated">If <c>true</c>, scrolling will be animated. Otherwise the cell will be moved instantaneously.</param>
        public void ApplyScrollTo(Cell cell, ScrollToPosition position, bool animated)
        {
            GenListItem item = GetItemContext(cell)?.Item as GenListItem;

            if (item != null)
            {
                this.ScrollTo(item, position.ToNative(), animated);
            }
        }
Beispiel #20
0
        public ScrollToRequestEventArgs(object item, object group,
                                        ScrollToPosition scrollToPosition, bool isAnimated)
        {
            Mode = ScrollToMode.Element;

            Item             = item;
            Group            = group;
            ScrollToPosition = scrollToPosition;
            IsAnimated       = isAnimated;
        }
Beispiel #21
0
        public ScrollToRequestEventArgs(int index, int groupIndex,
                                        ScrollToPosition scrollToPosition, bool isAnimated)
        {
            Mode = ScrollToMode.Position;

            Index            = index;
            GroupIndex       = groupIndex;
            ScrollToPosition = scrollToPosition;
            IsAnimated       = isAnimated;
        }
Beispiel #22
0
        public static UICollectionViewScrollPosition ToCollectionViewScrollPosition(this ScrollToPosition scrollToPosition,
                                                                                    UICollectionViewScrollDirection scrollDirection = UICollectionViewScrollDirection.Vertical, bool isLtr = false)
        {
            if (scrollDirection == UICollectionViewScrollDirection.Horizontal)
            {
                return(scrollToPosition.ToHorizontalCollectionViewScrollPosition(isLtr));
            }

            return(scrollToPosition.ToVerticalCollectionViewScrollPosition());
        }
Beispiel #23
0
 /// <summary>
 /// Shows a given item to the visible area of a gengrid.
 /// </summary>
 /// <param name="item">The gengrid item to display.</param>
 /// <param name="position">The position of the item in the viewport.</param>
 /// <param name="animated">The type of how to show the item.</param>
 /// <remarks>
 /// If animated is true, the gengrid shows the item by scrolling if it's not fully visible.
 /// If animated is false, the gengrid shows the item by jumping if it's not fully visible.
 /// </remarks>
 /// <seealso cref="ScrollToPosition"/>
 /// <since_tizen> preview </since_tizen>
 public void ScrollTo(GenGridItem item, ScrollToPosition position, bool animated)
 {
     if (animated)
     {
         Interop.Elementary.elm_gengrid_item_bring_in(item.Handle, (int)position);
     }
     else
     {
         Interop.Elementary.elm_gengrid_item_show(item.Handle, (int)position);
     }
 }
Beispiel #24
0
 /// <summary>
 /// Shows the given item with the position type in a genlist.
 /// When animated is true, the genlist will jump to the given item and display it (by animatedly scrolling), if it is not fully visible. This may use animation and take sometime.
 /// When animated is false, the genlist will jump to the given item and display it (by jumping to that position), if it is not fully visible.
 /// </summary>
 /// <param name="item">The item to display.</param>
 /// <param name="position">The position to show the given item to <see cref="ScrollToPosition"/>.</param>
 /// <param name="animated">The animated indicates how to display the item, by scrolling or by jumping.</param>
 /// <since_tizen> preview </since_tizen>
 public void ScrollTo(GenListItem item, ScrollToPosition position, bool animated)
 {
     if (animated)
     {
         Interop.Elementary.elm_genlist_item_bring_in(item.Handle, (Interop.Elementary.Elm_Genlist_Item_Scrollto_Type)position);
     }
     else
     {
         Interop.Elementary.elm_genlist_item_show(item.Handle, (Interop.Elementary.Elm_Genlist_Item_Scrollto_Type)position);
     }
 }
Beispiel #25
0
		public void ScrollTo(object item, ScrollToPosition position, bool animated)
		{
			if (!Enum.IsDefined(typeof(ScrollToPosition), position))
				throw new ArgumentException("position is not a valid ScrollToPosition", "position");

			var args = new ScrollToRequestedEventArgs(item, position, animated);
			if (IsPlatformEnabled)
				OnScrollToRequested(args);
			else
				_pendingScroll = args;
		}
Beispiel #26
0
        public ScrollToRequestEventArgs(object item, object group,
                                        ScrollToPosition scrollToPosition, bool isAnimated)
        {
            CollectionView.VerifyCollectionViewFlagEnabled(nameof(ScrollToRequestEventArgs));

            Mode = ScrollToMode.Element;

            Item             = item;
            Group            = group;
            ScrollToPosition = scrollToPosition;
            IsAnimated       = isAnimated;
        }
        public void ScrollTo(object data, ScrollToPosition position, bool animation)
        {
            var view = _itemsRootLayout.Children.FirstOrDefault(v => v.BindingContext == data);

            if (view != null)
            {
                Device.BeginInvokeOnMainThread(async() =>
                {
                    await _scrollView.ScrollToAsync(view, position, animation);
                });
            }
        }
Beispiel #28
0
        public ScrollToRequestEventArgs(int index, int groupIndex,
                                        ScrollToPosition scrollToPosition, bool isAnimated)
        {
            CollectionView.VerifyCollectionViewFlagEnabled(nameof(ScrollToRequestEventArgs));

            Mode = ScrollToMode.Position;

            Index            = index;
            GroupIndex       = groupIndex;
            ScrollToPosition = scrollToPosition;
            IsAnimated       = isAnimated;
        }
        async Task AnimateTo(ListViewBase list, object targetItem, ScrollToPosition scrollToPosition)
        {
            var scrollViewer = list.GetFirstDescendant <ScrollViewer>();

            var targetContainer = list.ContainerFromItem(targetItem) as UIElement;

            if (targetContainer == null)
            {
                var horizontalOffset = scrollViewer.HorizontalOffset;
                var verticalOffset   = scrollViewer.VerticalOffset;

                await JumpTo(list, targetItem, scrollToPosition);

                targetContainer = list.ContainerFromItem(targetItem) as UIElement;
                await ChangeViewAsync(scrollViewer, horizontalOffset, verticalOffset, true);
            }

            if (targetContainer == null)
            {
                // Did not find the target item anywhere
                return;
            }

            // TODO hartez 2018/10/04 16:37:35 Okay, this sort of works for vertical lists but fails totally on horizontal lists.
            var transform = targetContainer.TransformToVisual(scrollViewer.Content as UIElement);
            var position  = transform?.TransformPoint(new Windows.Foundation.Point(0, 0));

            if (!position.HasValue)
            {
                return;
            }

            // TODO hartez 2018/10/05 17:23:23 The animated scroll works fine vertically if we are scrolling to a greater Y offset.
            // If we're scrolling back up to a lower Y offset, it just gives up and sends us to 0 (first item)
            // Works fine if we disable animation, but that's not very helpful

            scrollViewer.ChangeView(position.Value.X, position.Value.Y, null, false);

            //if (scrollToPosition == ScrollToPosition.End)
            //{
            //	// Modify position
            //}
            //else if (scrollToPosition == ScrollToPosition.Center)
            //{
            //	// Modify position
            //}
            //else
            //{

            //}
        }
 private void ScrollToMessageIndex(int index, ScrollToPosition position, Action callback = null)
 {
     Device.BeginInvokeOnMainThread(() =>
     {
         try
         {
             MessagesListView.ScrollTo(vm.MessagesList[index], position, false);
             callback?.Invoke();
         }
         catch
         {
         }
     });
 }
        void Handle_Clicked(object sender, System.EventArgs e)
        {
            var vm = BindingContext as CollectionViewTestViewModel;

            collectionView.ScrollTo(vm.ItemsSource[9], pos, false);

            if (pos == ScrollToPosition.End)
            {
                pos = ScrollToPosition.Start;
            }
            else
            {
                pos++;
            }
        }
Beispiel #32
0
 /// <summary>
 /// Scrolls list to specified item
 /// </summary>
 /// <param name="item">Item.</param>
 /// <param name="position">Position.</param>
 /// <param name="animated">If set to <c>true</c> animated.</param>
 public void FlowScrollTo(object item, ScrollToPosition position, bool animated)
 {
     if (!IsGroupingEnabled)
     {
         var castedItemsSource = ItemsSource as IEnumerable <object>;
         var internalItem      = castedItemsSource?.FirstOrDefault(v => v == item || ((v as IEnumerable)?.Cast <object>().Contains(item)).GetValueOrDefault());
         ScrollTo(internalItem, position, animated);
     }
     else
     {
         var castedItemsSource = ItemsSource as IEnumerable <FlowGroup>;
         var internalItem      = castedItemsSource?.Select(v => v.FirstOrDefault(itm => ((itm as IEnumerable)?.Cast <object>().Contains(item)).GetValueOrDefault())).FirstOrDefault(v => v != null);
         ScrollTo(internalItem, position, animated);
     }
 }
Beispiel #33
0
        internal static void JumpToIndexAsync(ListViewBase list, int index, ScrollToPosition scrollToPosition)
        {
            var scrollViewer = list.GetFirstDescendant <ScrollViewer>();
            var con          = list.ContainerFromIndex(index);

            if (con is UIElement uIElement)
            {
                var width = uIElement.DesiredSize.Width;

                var current = scrollViewer.HorizontalOffset;
                var delta   = (index * width) - current;

                scrollViewer.ChangeView(current + delta, scrollViewer.VerticalOffset, scrollViewer.ZoomFactor, true);
            }
        }
Beispiel #34
0
		Point IScrollViewController.GetScrollPositionForElement(VisualElement item, ScrollToPosition pos)
		{
			ScrollToPosition position = pos;
			double y = GetCoordinate(item, "Y", 0);
			double x = GetCoordinate(item, "X", 0);

			if (position == ScrollToPosition.MakeVisible)
			{
				bool isItemVisible = ScrollX < y && ScrollY + Height > y;
				if (isItemVisible)
					return new Point(ScrollX, ScrollY);
				switch (Orientation)
				{
					case ScrollOrientation.Vertical:
						position = y > ScrollY ? ScrollToPosition.End : ScrollToPosition.Start;
						break;
					case ScrollOrientation.Horizontal:
						position = x > ScrollX ? ScrollToPosition.End : ScrollToPosition.Start;
						break;
					case ScrollOrientation.Both:
						position = x > ScrollX || y > ScrollY ? ScrollToPosition.End : ScrollToPosition.Start;
						break;
				}
			}
			switch (position)
			{
				case ScrollToPosition.Center:
					y = y - Height / 2 + item.Height / 2;
					x = x - Width / 2 + item.Width / 2;
					break;
				case ScrollToPosition.End:
					y = y - Height + item.Height;
					x = x - Width + item.Width;
					break;
			}
			return new Point(x, y);
		}
Beispiel #35
0
		public Task ScrollToAsync(Element element, ScrollToPosition position, bool animated)
		{
			if (!Enum.IsDefined(typeof(ScrollToPosition), position))
				throw new ArgumentException("position is not a valid ScrollToPosition", "position");

			if (element == null)
				throw new ArgumentNullException("element");

			if (!CheckElementBelongsToScrollViewer(element))
				throw new ArgumentException("element does not belong to this ScrollVIew", "element");

			var args = new ScrollToRequestedEventArgs(element, position, animated);
			OnScrollToRequested(args);
			return _scrollCompletionSource.Task;
		}