maui
maui copied to clipboard
Grouped CollectionView lazy loading does not trigger [RemainingItemsThresholdReached] on iOS and Windows
Description
When populating a CollectionView with grouped data, the [RemainingItemsThresholdReached] event does not trigger for iOS and Windows when the [RemainingItemsThreshold] value is reached.
This works fine under Android.
A simple repro is provided.
See here how Android works (must admit, it throws a low-level exception each time the threshold is reached, but maybe that is by design)
https://user-images.githubusercontent.com/7484186/189766047-067038e0-0c7d-4184-b3c1-3944c2ed3eac.mp4
See here how iOS only loads the first chunk, then never triggers when scrolled down.
https://user-images.githubusercontent.com/7484186/189766117-98eec0a2-c54b-4a45-b5f6-8da9cf036158.mp4
See here how Windows loads the first chunk, then never triggers when scrolled down.
https://user-images.githubusercontent.com/7484186/189766169-101b873b-9c7d-4b7a-bdaf-f9dbb359f684.mp4
Steps to Reproduce
- Load the project in VS from the Github repro
- Run the app for the three projects
- The applicable code is in file [StartupPage.cs]
Link to public reproduction project repository
https://github.com/hbraasch/ChunkTester.git
Version with bug
6.0.400
Last version that worked well
Unknown/Other
Affected platforms
iOS, Windows
Affected platform versions
Android 12 - API 31, windows10.0.19041.0
Did you find any workaround?
No
Relevant log output
No response
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
I consider this a serious problem. Since your [Image] component does not cache local files, it can take quite a long while to populate a CollectionView with images in its items. Lazy loading is the solution to this. Without a working lazy loading, it makes for a very frustrating user experience. Please reconsider this categorization.
Please have a look at this - it is a show-stopper for Xamarin migration. @PureWeen, @jsuarezruiz
@hbraasch @SophisticatedConsulting Try this temporary solution in Windows:
<CollectionView Scrolled="CollectionView_Scrolled"/>
private void CollectionView_Scrolled(object sender, ItemsViewScrolledEventArgs e)
{
//TODO WinUI 中,目前无法触发 RemainingItemsThresholdReachedCommand,因此先自己实现一下
if (DeviceInfo.Current.Platform != DevicePlatform.WinUI)
{
return;
}
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);
}
}
}
}
Thanks for the proposal @JiuLing-zhang.
Unfortunately, this does not work with a Grouped CollectionView - the EventArgs passed references the current group in the CollectionView (all of which is always visible). In my case this is a group of 20 items displayed vertically and which should add additional groups when scrolled horizontally. e.LastVisibleItemIndex is always 20 and less than element.LogicalChildren.Count.
It is not possible (as far as I can see) to find out when you have scrolled to the last group in the CollectionView and add the next.
If I remove the check, then the scroll event is called far too often and the CollectionView is populated with too many groups.
Any ideas?
Verified this issue with Visual Studio 17.7.0 Preview 1.0. Can repro on windows and iOS platform with above project. Android works fine.
ChunkTester-master.zip
Android:
Windows:
iOS:
In #13391 I posted a workaround that fixes the problem for me on iOS.
Something worth mentioning, even with the workaround it only worked for me when RemainingItemsThreshold was different from 0.
The issue also repro on Android platform. Build version: 17.9.0 Preview 3.0 [34420.99.main] Microsoft.Maui.Controls: 8.0.6-nightly.9783+sha.4d833eab0d-azdo.8835091 Android Api version: API 34 [ManualMauiTests.zip]
I am still experiencing this problem on iPad
Our little bug is already 4 years old, he grows up so fast. It even learned to do its thing in .NET 8, I am so proud!
Thanks for the updated workaround with handler @naaeef
We faced this issue again while we were on dotNet 8, and I used the @JiuLing-zhang suggestion and solved my issue that on iOS it was not working for static threshold
RemainingItemsThresholdReachedCommand doesn't trigger on Android either (net maui 8 latest). This is a show stopper.
Still having this issue on IOS. seems like this one should be a bit more of a priority item, considering its an old "bug" still present and causing issues for quite a few people.
Still having this issue on IOS. seems like this one should be a bit more of a priority item, considering its an old "bug" still present and causing issues for quite a few people.
I agree. Did this but get lost in the backrooms? I mean, backlogs?
Why is this getting shelved? This is a serious issue you have code submitted to demonstrate and fix the issue and issues like this really prevents MAUI from being taken serious.
Still having this issue ! Please fix this and all the bugs with grouped collection...
For me this works in iOS when there is only 1 group in CollectionView but if there are more than 1 groups then this command does not fire and hence lazy loading stopped working in this case.
And fortunately https://github.com/dotnet/maui/issues/13391#issuecomment-1833506867 this workaround solved it.
Incredible that such a basic feature is still broken.
Incredible that such a basic feature is still broken.
Damn i know right
One intresting thing to note is that the RemainingItemsThresholdReached does get triggered when scrolling if the RemainingItemsThreshold is a number slightly bigger than the number of groups currently being displayed.
This is of course not ideal because it gets triggered right away when starting to scroll, and does not work after loading more items, if the new number of groups being displayed is now bigger than the RemainingItemsThreshold.
I couldn't determine the logic for the threshold needed to trigger the ThresholdReached. It seems to be affected by the number of groups, the number of items within a group, and the empty groups.
For example, in my testing: 20 groups displayed, with 20 items scattered, needed a threshold of 23 to get triggered. 21 groups displayed, with 23 items, needed a threshold of 26 to get triggered. 22 groups displayed, with 23 items, needed a threshold of 27 to get triggered. 22 groups displayed, with 24 items, needed a threshold of 28 to get triggered. 22 groups displayed, with 25 items, needed a threshold of 28 to get triggered. (note: same threshold as previous)
Was hoping that migrating to .net9 would fix my issues with lazy loading but it did not. Then I switch all my newly depreciated frames to borders and all my lazy loading issues went away. A lot of these seemingly random issues in maui seem to be triggered by certain combinations of layouts and/or views not playing nicely.
Was hoping that migrating to .net9 would fix my issues with lazy loading but it did not. Then I switch all my newly depreciated frames to borders and all my lazy loading issues went away. A lot of these seemingly random issues in maui seem to be triggered by certain combinations of layouts and/or views not playing nicely.
How did this happen and why? weird
Hi guys, I don't feel like this is a problem anymore (dotnet9 + CollectionViewHandler2 on ios) on my actual project but every case is different. Can you check on your side so we can eventualy close the subject ?
The command is correctly called in Net8 / Windows, IOS, Android
collectionView.ItemsUpdatingScrollMode = ItemsUpdatingScrollMode.KeepScrollOffset;
collectionView.RemainingItemsThreshold = 1;
collectionView.Bind(CollectionView.RemainingItemsThresholdReachedCommandProperty,
(StoryShowViewModel vm) => vm.LoadMoreDataCommand,
mode: BindingMode.OneTime);
but the ItemsUpdatingScrollMode does not work. This is another open issue #17836. After adding new items, the collectionview jumps to the first item. This, for me, is a bad issue, so i have to use pagewise loading with forward and backward buttons. Very old style.
Issue can be closed
I must dig a bit deeper but, to me, the RemainingItemsThresholdReachedCommand don't tick anymore with the last version of MAUI (9.0.40). I tried rolling back to 9.0.30 and it worked again :(
Good thing this issue was not closed !
On Windows, RemainingItemsThresholdReachedCommand and RemainingItemsThresholdReached event works with 9.0.40
IOS 9.0.60 is not working. Any updates on this? @jfversluis
This issue cannot be reproduced with the iOS CollectionView2 handler. Could you try using the new handler to see if it resolves the issue on iOS?
That would be great, I'll update my reproduction project and report back. It would be nice to get rid of workarounds after 6 years https://github.com/xamarin/Xamarin.Forms/issues/8383