Search code examples
mauicollectionview

Issue with CollectionView RemainingItemsThresholdReached event


I am facing 2 issues with the CollectionView:

  1. I have given RemainingItemsThreshold="0" for CollectionView, but the RemainingItemsThresholdReached event is firing before reaching the last item. It is calling around 6 items before the last item.
  2. WhenRemainingItemsThresholdReached is fired, I load the next set of data and append it to the CollectionView. But at that time, the CollectionView is scroll to the first item. It is not stay on the last item where we load more data.

My CollectionView Code:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage 
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    BackgroundColor="White"
    x:Class="NeedHelp.Pages.FriendDetailsPage">

    <ContentPage.Content>
        <StackLayout>
            <Grid BackgroundColor="#eeeeee">
                
            </Grid>

            <ScrollView 
                x:Name="frienddetails_scrollview"
                IsVisible="False"
                Orientation="Vertical" 
                VerticalOptions="FillAndExpand" 
                HorizontalOptions="FillAndExpand">
                
                <StackLayout
                    Margin="15">
                    
                    <Frame 
                        BorderColor="#efefef"
                        BackgroundColor="White"
                        CornerRadius="5"
                        HasShadow="False"
                        Padding="5">
                        
                    </Frame>

                    <Frame
                        BorderColor="#efefef"
                        Padding="3"
                        x:Name="map_layout"
                        Margin="0,5,0,0">
                        
                    </Frame>

                    <Label
                        Margin="0,5,0,0"
                        x:Name="History_label"
                        Text="History"
                        TextColor="#424242"
                        HorizontalOptions="Center"
                        HorizontalTextAlignment="Center">
                    </Label>

                    <Frame
                        x:Name="Tab_layout"
                        BorderColor="#efefef"
                        Margin="0,5,0,0"
                        BackgroundColor="White"
                        HasShadow="False"
                        CornerRadius="5"
                        Padding="5">

                    </Frame>

                    <ListView 
                        x:Name="historylistview"
                        SeparatorVisibility="None"
                        HasUnevenRows="True"
                        SelectionMode="None"
                        CachingStrategy="RecycleElement"
                        BackgroundColor="#ffffff">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <ViewCell>
                                    <ViewCell.View>
                                        <StackLayout
                                            Margin="0,0,0,10">
                                            
                                        </StackLayout>
                                    </ViewCell.View>
                                </ViewCell>
                            </DataTemplate>
                        </ListView.ItemTemplate>

                        <ListView.Footer>
                            <Label/>
                        </ListView.Footer>
                    </ListView>

                    <CollectionView 
                        x:Name="MyTweetsList" 
                        Margin="0,5,0,5"
                        ItemsSource="{Binding AllItems,Mode=TwoWay}"
                        RemainingItemsThreshold="0"
                        RemainingItemsThresholdReached="LoadMoreTweets"
                        HorizontalOptions="Fill">
                        <CollectionView.ItemTemplate>
                            <DataTemplate>
                                <StackLayout
                                    x:Name="Item"
                                    HorizontalOptions="Fill"
                                    VerticalOptions="FillAndExpand"
                                    Orientation="Vertical">

                                </StackLayout>
                            </DataTemplate>
                        </CollectionView.ItemTemplate>
                        <CollectionView.HeightRequest>
                            <OnIdiom x:TypeArguments="x:Double">
                                <OnIdiom.Phone>400</OnIdiom.Phone>
                                <OnIdiom.Tablet>600</OnIdiom.Tablet>
                                <OnIdiom.Desktop>400</OnIdiom.Desktop>
                            </OnIdiom>
                        </CollectionView.HeightRequest>
                    </CollectionView>

                    <Label
                        VerticalOptions="CenterAndExpand"
                        HorizontalOptions="CenterAndExpand"
                        IsVisible="{Binding ComingSoonVisibility}"
                        HorizontalTextAlignment="Center"
                        Text="No Messages Yet."
                        x:Name="no_announcement_label"/>
                </StackLayout>
            </ScrollView>
            
            <Grid 
                x:Name="tweetBox"
                IsVisible="False"
                Margin="0,0,0,10">

            </Grid>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Update

I have created a demo with this issue.

In this demo I am loading 50 items initially and after that loading 10 items. After loading the last 10, the collectionview scrolls to top and showing the initial items.


Solution

  • Your main problem:

    This line

    AllItems = new ObservableCollection<UserTweetsList>(Items);
    

    Is causing your whole collection view to refresh. The whole point of observable collection is to make changes to the list. Recreating the collection, besides other performance issues, is the thing causing your scroll to go to the start.

    Your solution:

    Use AllItems = new only once. And then use AllItems.Add(..) when you are loading items.

    For example

    if (!loadMore)
    {
       Items.Add(new UserTweetsList() { tweetData = "message 1", tweetUser = "Albert});
       ...
       Items.Add(new UserTweetsList() { tweetData = "message 50", tweetUser = "Albert"});
       AllItems = new ObservableCollection<UserTweetsList>(Items); << move here
    }
    else
    {
        AllItems.Add(new UserTweetsList() { tweetData = "message 51", tweetUser = "Albert" }); << change those lines to AllItems.Add not Items.Add