Xamarin.forms: [Bug] [UWP] RemainingItemsThresholdReachedCommand in CollectionView is not working

Created on 24 Dec 2019  路  3Comments  路  Source: xamarin/Xamarin.Forms

Description

It's not working on UWP but It's working on Android.

Steps to Reproduce

  1. Run the app.
  2. Scroll down to the fiftieth item.

Expected Behavior

Triggering the binded command.

Actual Behavior

Nothing is happened.

Basic Information

  • Version with issue:
    4.4.0.991265
  • Last known good version: -
  • IDE:
    Visual Studio 2019 16.4.2
  • Platform Target Frameworks:

    • iOS: -

    • Android: 9.0

    • UWP: 16299

  • Nuget Packages:-
  • Affected Devices: Windows 10 1909 build 18363.535

Reproduction Link


CollectionViewTestProject.zip

collectionview 4 in-progress UWP bug up-for-grabs

Most helpful comment

I have written myself a temp workaround for this.

First, in the Collection View XAML add Scrolled event handler

<CollectionView ...
                         ...
Scrolled="CollectionView_OnScrolled">

Then in code behind:

private void CollectionView_OnScrolled(object sender, ItemsViewScrolledEventArgs e)
        {
            if (Device.RuntimePlatform != Device.UWP)
            {
                return;
            }

            if (sender is CollectionView cv)
            {
                var count = cv.ItemsSource.Cast<ICollection>().Sum(c => c.Count);
                if (e.LastVisibleItemIndex + 1 - count + cv.RemainingItemsThreshold >= 0)
                {
                   if (cv.RemainingItemsThresholdReachedCommand.CanExecute(null))
                        cv.RemainingItemsThresholdReachedCommand.Execute(null);
                }
            }
        }

I've tried to use your workaround to make my infinitescroll work, changing the reacheadcommand to my Reached method but I had 2 problems:
Is "(cv.ItemsSource as ICollection).Count" the same as "cv.ItemsSource.Cast().Sum(c => c.Count)"? And LastVisibleItemIndex won't update for me after updating the collectionview collection

All 3 comments

I have written myself a temp workaround for this.

First, in the Collection View XAML add Scrolled event handler

<CollectionView ...
                         ...
Scrolled="CollectionView_OnScrolled">

Then in code behind:

private void CollectionView_OnScrolled(object sender, ItemsViewScrolledEventArgs e)
        {
            if (Device.RuntimePlatform != Device.UWP)
            {
                return;
            }

            if (sender is CollectionView cv)
            {
                var count = cv.ItemsSource.Cast<ICollection>().Sum(c => c.Count);
                if (e.LastVisibleItemIndex + 1 - count + cv.RemainingItemsThreshold >= 0)
                {
                   if (cv.RemainingItemsThresholdReachedCommand.CanExecute(null))
                        cv.RemainingItemsThresholdReachedCommand.Execute(null);
                }
            }
        }

I have written myself a temp workaround for this.

First, in the Collection View XAML add Scrolled event handler

<CollectionView ...
                         ...
Scrolled="CollectionView_OnScrolled">

Then in code behind:

private void CollectionView_OnScrolled(object sender, ItemsViewScrolledEventArgs e)
        {
            if (Device.RuntimePlatform != Device.UWP)
            {
                return;
            }

            if (sender is CollectionView cv)
            {
                var count = cv.ItemsSource.Cast<ICollection>().Sum(c => c.Count);
                if (e.LastVisibleItemIndex + 1 - count + cv.RemainingItemsThreshold >= 0)
                {
                   if (cv.RemainingItemsThresholdReachedCommand.CanExecute(null))
                        cv.RemainingItemsThresholdReachedCommand.Execute(null);
                }
            }
        }

I've tried to use your workaround to make my infinitescroll work, changing the reacheadcommand to my Reached method but I had 2 problems:
Is "(cv.ItemsSource as ICollection).Count" the same as "cv.ItemsSource.Cast().Sum(c => c.Count)"? And LastVisibleItemIndex won't update for me after updating the collectionview collection

The code from @artur170dx worked for me. (Almost)
As the items are cached, I needed a trick to get the logical children count instead of itemsource count.

if (sender is CollectionView cv && cv is IElementController element)
            {
                var count = element.LogicalChildren.Count;
                if (e.LastVisibleItemIndex + 1 - count + cv.RemainingItemsThreshold >= 0)
                {
                    if (cv.RemainingItemsThresholdReachedCommand.CanExecute(null))
                        cv.RemainingItemsThresholdReachedCommand.Execute(null);
                }
            }
Was this page helpful?
0 / 5 - 0 ratings