xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

[Bug] Pull-to-refresh (RefreshView) triggers RemainingItemsThresholdReachedCommand #11632

Open Kapusch opened 4 years ago

Kapusch commented 4 years ago

Description

I have a CollectionView inside a RefreshView, and my CollectionView enables incremental load. The two components work great, but I have noticed that pulling to refresh triggers the RemainingItemsThresholdReachedCommand.

Some conditions are required to easily encounter this bug :

Note : I did not test under Android.

Steps to Reproduce

  1. Open the demo project to reproduce the bug
  2. Pull-to-refresh the list
  3. You can observe the bug via displayed alerts, or even with Console logs (but you'll have to disable alerts if you want to make refresh happens).

Expected Behavior

When I pull-to-refresh, I expect that the RefreshView Command , instead of loading more content with RemainingItemsThresholdReachedCommand.

Actual Behavior

As described in the .GIF below, you can see that RemainingItemsThresholdReachedCommand is triggered everytime I start pull-to-refresh gesture.

Basic Information

Screenshots

XF_Bug_RefreshView_IncrementalLoad

Reproduction Link

https://github.com/Kapusch/XF_Bug_RefreshView_IncrementalLoad

Workaround

Not applicable if the maximum content length is low, but here is a workaround for other cases :

Tommigun1980 commented 4 years ago

I gave up on the refresh view as it never works properly. It will probably take a couple more years for these things to stabilise so you might want to look into alternative designs.

Kapusch commented 3 years ago

WORKAROUND

I have surprisingly solved this problem by using the AsyncCommand provided in Xamarin.CommunityToolkit, disabling "AllowMultipleExecutions" property:

public ICommand SignOutCommand => new AsyncCommand(SignOutCommandAsync, allowsMultipleExecutions: false);
private async Task SignOutCommandAsync()
{
    try
    {
        await base.SignOut();
    }
    catch (Exception ex)
    {
        await DispatchError(new BaseException(ex), UIElementIds.AccountSettingsScreen);
    }
}

Here are some useful links if you want to give a try :