CollectionView's RemainingItemsThresholdReached event firing before loading the data on UI

Sreejith Sreenivasan 896 Reputation points
2024-08-07T13:48:49.13+00:00

I have a collectionview on my UI and I load 20 items initially. I have added RemainingItemsThresholdReached event for loading next 20 items when I reach the end of first 20 items. But after loading first 20 it is instantly load the next 20 and again load the next 20 and repeated up to load all the items.

I have added the same kind of logic on a different page and on there it is working fine. So I suspect the issue is with the layout used on that page. Below I have added the layout structure I am using.

<?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" 
    xmlns:rgAnimations="clr-namespace:RGPopup.Maui.Animations;assembly=RGPopup.Maui" 
    xmlns:pages="clr-namespace:RGPopup.Maui.Pages;assembly=RGPopup.Maui"
    NavigationPage.HasNavigationBar="false"
    xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
    xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials"
    xmlns:ffimageloading="clr-namespace:FFImageLoading.Maui;assembly=FFImageLoading.Maui"
    xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Maui"
    BackgroundColor="White">

    <ContentPage.Resources>
        <ResourceDictionary>
            <local2:ProfileNameConverter x:Key="nameConverter"></local2:ProfileNameConverter>
            <local3:DatetimeToStringConverter x:Key="cnvDateTimeConverter"></local3:DatetimeToStringConverter>
            <local3:TweetUrlsLinkconverter x:Key="urlJoinConverter"></local3:TweetUrlsLinkconverter>
            <local3:SpecialCharactorConverter x:Key="specialCharactorConverter"></local3:SpecialCharactorConverter>
        </ResourceDictionary>
    </ContentPage.Resources>
    
    <ContentPage.Content>
        <StackLayout>
            <Grid BackgroundColor="#eeeeee">
                <Grid.RowDefinitions>
                    <RowDefinition Height="{OnIdiom Phone=60, Tablet=90, Desktop=60}" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="1.5*" />
                    <ColumnDefinition Width="7*" />
                    <ColumnDefinition Width="1.5*" />
                </Grid.ColumnDefinitions>

                    //Header layout
                
            </Grid>

            <ScrollView 
                x:Name="frienddetails_scrollview"
                IsVisible="False"
                Orientation="Vertical" 
                VerticalOptions="FillAndExpand" 
                HorizontalOptions="FillAndExpand">
                
                <StackLayout
                    Margin="15">
                    
                    //Middle layout

                    <CollectionView 
                        x:Name="historyCollectionView"
                        SelectionMode="None"
                        RemainingItemsThreshold="1"
                        RemainingItemsThresholdReached="LoadMoreHistory"
                        BackgroundColor="#ffffff">
                        <CollectionView.ItemTemplate>
                            <DataTemplate>
                                <StackLayout
                                    Margin="0,0,0,10">
                                    <StackLayout
                                        x:Name="Day_layout"
                                        Orientation="Vertical"
                                        BackgroundColor="#eeeeee"
                                        Padding="5">
                                        
                                        <Label
                                            Text="{Binding userLocationTO.createdTime,Converter={StaticResource cnvDateTimeConverter}}"
                                            TextColor="#313131"
                                            Margin="10,0,0,0"
                                            HorizontalOptions="Start"
                                            HorizontalTextAlignment="Center">
                                            <Label.FontSize>
                                                <OnIdiom x:TypeArguments="x:Double">
                                                    <OnIdiom.Phone>18</OnIdiom.Phone>
                                                    <OnIdiom.Tablet>27</OnIdiom.Tablet>
                                                    <OnIdiom.Desktop>18</OnIdiom.Desktop>
                                                </OnIdiom>
                                            </Label.FontSize>
                                        </Label>
                                    </StackLayout>

                                    <Grid Margin="10,0,0,0">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="10*" />
                                            <!--<ColumnDefinition Width="4*" />-->
                                        </Grid.ColumnDefinitions>

                                        <StackLayout
                                            Grid.Column="0"
                                            Orientation="Vertical">
                                            <StackLayout
                                                Orientation="Horizontal"
                                                Margin="0,10,0,0">
                                                <Image 
                                                    Source="{Binding IconType}"
                                                    VerticalOptions="CenterAndExpand"
                                                    HorizontalOptions="Start">
                                                    <Image.WidthRequest>
                                                        <OnIdiom x:TypeArguments="x:Double">
                                                            <OnIdiom.Phone>20</OnIdiom.Phone>
                                                            <OnIdiom.Tablet>30</OnIdiom.Tablet>
                                                            <OnIdiom.Desktop>20</OnIdiom.Desktop>
                                                        </OnIdiom>
                                                    </Image.WidthRequest>
                                                    <Image.HeightRequest>
                                                        <OnIdiom x:TypeArguments="x:Double">
                                                            <OnIdiom.Phone>20</OnIdiom.Phone>
                                                            <OnIdiom.Tablet>30</OnIdiom.Tablet>
                                                            <OnIdiom.Desktop>20</OnIdiom.Desktop>
                                                        </OnIdiom>
                                                    </Image.HeightRequest>
                                                </Image>

                                                <Label 
                                                    x:Name="Emergency_label"
                                                    Text="{Binding triggerType}"
                                                    HorizontalOptions="Start"
                                                    VerticalOptions="CenterAndExpand"
                                                    TextColor="#1c98d7">
                                                    <Label.FontSize>
                                                        <OnIdiom x:TypeArguments="x:Double">
                                                            <OnIdiom.Phone>16</OnIdiom.Phone>
                                                            <OnIdiom.Tablet>24</OnIdiom.Tablet>
                                                            <OnIdiom.Desktop>16</OnIdiom.Desktop>
                                                        </OnIdiom>
                                                    </Label.FontSize>
                                                </Label>
                                            </StackLayout>


                                            <Grid>
                                                <Label 
                                                    Text="{Binding AllAudits}"
                                                    HorizontalOptions="Start"
                                                    VerticalOptions="CenterAndExpand"
                                                    Margin="0,2,0,8"
                                                    TextColor="#545454">
                                                    <Label.FontSize>
                                                        <OnIdiom x:TypeArguments="x:Double">
                                                            <OnIdiom.Phone>14</OnIdiom.Phone>
                                                            <OnIdiom.Tablet>21</OnIdiom.Tablet>
                                                            <OnIdiom.Desktop>14</OnIdiom.Desktop>
                                                        </OnIdiom>
                                                    </Label.FontSize>
                                                </Label>
                                            </Grid>
                                        </StackLayout>
                                    </Grid>
                                </StackLayout>
                            </DataTemplate>
                        </CollectionView.ItemTemplate>
                    </CollectionView>

                    <Label
                        VerticalOptions="CenterAndExpand"
                        HorizontalOptions="CenterAndExpand"
                        HorizontalTextAlignment="Center"
                        IsVisible="False"
                        Text="No history found!"
                        x:Name="no_history_label">
                        <Label.FontFamily>
                            <OnPlatform x:TypeArguments="x:String">
                                <On Platform="iOS" Value="Roboto-Light" />
                                <On Platform="Android" Value="Roboto-Light.ttf#Roboto-Light" />
                                <On Platform="UWP" Value="Assets/Fonts/Roboto-Light.ttf#Roboto" />
                            </OnPlatform>
                        </Label.FontFamily>
                        <Label.FontSize>
                            <OnIdiom x:TypeArguments="x:Double">
                                <OnIdiom.Phone>18</OnIdiom.Phone>
                                <OnIdiom.Tablet>26</OnIdiom.Tablet>
                                <OnIdiom.Desktop>18</OnIdiom.Desktop>
                            </OnIdiom>
                        </Label.FontSize>
                    </Label>

                    <StackLayout x:Name="chat_stack" IsVisible="{Binding chatVisibility}" VerticalOptions="Fill" >
                        <StackLayout.HeightRequest>
                            <OnIdiom x:TypeArguments="x:Double">
                                <OnIdiom.Phone>600</OnIdiom.Phone>
                                <OnIdiom.Tablet>900</OnIdiom.Tablet>
                                <OnIdiom.Desktop>600</OnIdiom.Desktop>
                            </OnIdiom>
                        </StackLayout.HeightRequest>

                        <RefreshView  
                            IsVisible="{Binding chatVisibility}"
                            IsRefreshing="{Binding IsRefreshing}"
                            Command="{Binding RefreshCommand}">

                            <CollectionView 
                                x:Name="MyTweetsList" 
                                Margin="0,5,0,5"
                                ItemsSource="{Binding AllItems,Mode=TwoWay}"
                                RemainingItemsThreshold="0"
                                IsVisible="{Binding chatVisibility}"
                                RemainingItemsThresholdReached="LoadMoreTweets"
                                VerticalOptions="FillAndExpand"
                                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>
                        </RefreshView>
                    </StackLayout>

                    <Label
                        VerticalOptions="CenterAndExpand"
                        HorizontalOptions="CenterAndExpand"
                        IsVisible="{Binding ComingSoonVisibility}"
                        HorizontalTextAlignment="Center"
                        Text="No Messages Yet."
                        x:Name="no_announcement_label">
                        <Label.FontFamily>
                            <OnPlatform x:TypeArguments="x:String">
                                <On Platform="iOS" Value="Roboto-Light" />
                                <On Platform="Android" Value="Roboto-Light.ttf#Roboto-Light" />
                                <On Platform="UWP" Value="Assets/Fonts/Roboto-Light.ttf#Roboto" />
                            </OnPlatform>
                        </Label.FontFamily>
                        <Label.FontSize>
                            <OnIdiom x:TypeArguments="x:Double">
                                <OnIdiom.Phone>18</OnIdiom.Phone>
                                <OnIdiom.Tablet>26</OnIdiom.Tablet>
                                <OnIdiom.Desktop>18</OnIdiom.Desktop>
                            </OnIdiom>
                        </Label.FontSize>
                    </Label>
                </StackLayout>
            </ScrollView>
            
            <Grid 
                x:Name="tweetBox"
                IsVisible="False"
                Margin="0,0,0,10">

                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>

                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="8*" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>

                //message sending layout
            </Grid>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

I have issue with the historyCollectionView and have another CollectionView on the same page.

Can anyone tell what is the issue by checking the above xaml layout codes?

Updates:

xaml.cs codes

public partial class FriendDetailsPage : ContentPage
{
    public ObservableCollection<UserLocationHistoryHBList> allHistoryList;
    bool loadMoreHistory = false;
    bool haveHistoryItemsToLoad = false;
    
    public FriendDetailsPage(UserFriendHBList friendsdetails)
    {
        allHistoryList = new ObservableCollection<UserLocationHistoryHBList>();
        await Task.Run(async () => await SetHistoryListItems(monitorId));
    }
    
    public async Task SetHistoryListItems(string selecteduserId)
    {
        try
        {
            //API Call
            if (locationHistory.userLocationHistoryHBList != null)
            {
                if (locationHistory.userLocationHistoryHBList.Count != 0)
                {
                    foreach (var item in locationHistory.userLocationHistoryHBList)
                    {
                        //list iteration and adding list to collection
                        allHistoryList.Add(item);
                    }
                    MainThread.BeginInvokeOnMainThread(async () =>
                    {
                        //setting data to collectionview
                        historylistview.ItemsSource = allHistoryList;
                        UserDialogs.Instance.HideHud();
                    });
                    if (locationHistory.userLocationHistoryHBList.Count == 20)
                    {
                        haveHistoryItemsToLoad = true;
                    }
                    else
                    {
                        haveHistoryItemsToLoad = false;
                    }
                }
                else
                {
                    SetNoHistoryAlert();
                }
            }
            else
            {
                SetNoHistoryAlert();
            }
        }
        catch (Exception ex)
        {
            UserDialogs.Instance.HideHud();
            Debug.WriteLine("Exception:>" + ex);
        }
    }

    //Load more items API call
    void LoadMoreHistory(object sender, EventArgs e)
    {
        if (haveHistoryItemsToLoad)
        {
            haveHistoryItemsToLoad = false;
            loadMoreHistory = true;
            SetHistoryListItems(friendsdata.userId);
        }
    }
}
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,538 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Sreejith Sreenivasan 896 Reputation points
    2024-08-16T10:59:43.2066667+00:00

    We can fix this by explicitly setting a height for the CollectionView, or by placing it in a parent container that restricts its size, like a Frame or BoxView. This will ensure the RemainingItemsThresholdReached event only triggers when the user scrolls near the bottom of the currently visible items.

    Solution: Constrain the Height of the CollectionView

    Method 1: Explicit HeightRequest

    You can set an explicit height for the CollectionView, ensuring it doesn’t expand indefinitely.

    <!-- Setting an explicit HeightRequest -->
    <CollectionView 
        x:Name="historylistview"
        SelectionMode="None"
        RemainingItemsThreshold="1"
        RemainingItemsThresholdReached="LoadMoreHistory"
        BackgroundColor="#ffffff"
        HeightRequest="300"> <!-- Adjust this height based on the layout -->
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout
                    Margin="0,0,0,10">
                    <!-- My existing template code -->
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
    

    Method 2: Constrain Using Parent Container (e.g., Frame)

    Wrap the CollectionView in a Frame or BoxView with a constrained height:

    <!-- Wrapping the CollectionView in a Frame with a set height -->
    <Frame 
        VerticalOptions="FillAndExpand"
        HeightRequest="300" <!-- Adjust height as necessary -->
        BorderColor="Transparent"
        BackgroundColor="Transparent">
        <CollectionView 
            x:Name="historylistview"
            SelectionMode="None"
            RemainingItemsThreshold="1"
            RemainingItemsThresholdReached="LoadMoreHistory"
            BackgroundColor="#ffffff">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout
                        Margin="0,0,0,10">
                        <!-- My existing template code -->
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </Frame>
    
    • Explicit HeightRequest: Setting an explicit height ensures that the CollectionView does not expand to fit all its items, thus preventing the RemainingItemsThresholdReached event from firing too early.
    • Using a Parent Container with Set Height: Wrapping the CollectionView in a Frame with a defined HeightRequest ensures it occupies only the specified space, enabling incremental loading as expected.
    1 person found this answer helpful.

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.