C# 表单在CollectionView中实现延迟加载

C# 表单在CollectionView中实现延迟加载,c#,xamarin.forms,xamarin-community-toolkit,xamarin.forms.collectionview,C#,Xamarin.forms,Xamarin Community Toolkit,Xamarin.forms.collectionview,这是我的CollectionView xaml文件: <ContentPage.Content> <Grid> <StackLayout> <RefreshView IsRefreshing="{Binding IsRefreshing, Mode=OneWay}" Command="{Binding LoadRefre

这是我的CollectionView xaml文件:

    <ContentPage.Content>
        <Grid>
            <StackLayout>
                <RefreshView IsRefreshing="{Binding IsRefreshing, Mode=OneWay}"
             Command="{Binding LoadRefreshCommand}">
                    <CollectionView ItemsSource="{Binding Photos}" SelectedItem="{Binding SelectedPhoto}" RemainingItemsThreshold="10" RemainingItemsThresholdReachedCommand="{Binding LoadNewPhotosCommand}" >
                        <CollectionView.ItemTemplate>
                            <DataTemplate>
                                <Frame BorderColor="#3498DB">
                                    <Grid  RowSpacing="0" ColumnSpacing="0" Padding="0">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="3*"/>

                                        </Grid.ColumnDefinitions>
                                        <Grid.GestureRecognizers>
                                            <TapGestureRecognizer  Command="{Binding Source={x:Reference CurrentPage}, Path=BindingContext.LoadPhotosCommand}" />
                                        </Grid.GestureRecognizers>
                                        <Image Aspect="AspectFit" HeightRequest="50" Source="{Binding Url}"  Grid.Column="0"></Image>
                                        <Frame HasShadow="False" VerticalOptions="Center"  Grid.Column="1">
                                            <Label Text="{Binding Title}"></Label>
                                        </Frame>
                                    </Grid>
                                </Frame>
                            </DataTemplate>
                        </CollectionView.ItemTemplate>
                    </CollectionView>
                </RefreshView>
            </StackLayout>
            <StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="Center">
                <Frame IsVisible="{Binding IsBusy}" BorderColor="#3498DB" HasShadow="False" BackgroundColor="#eeeeee">
                    <StackLayout>
                        <ActivityIndicator IsVisible="{Binding IsBusy}" IsRunning="{Binding IsBusy}" HorizontalOptions="Center" VerticalOptions="Center"></ActivityIndicator>
                        <Label TextColor="#3498DB" Text="Loading Data, Please Wait..." HorizontalTextAlignment="Center" VerticalTextAlignment="Center" HorizontalOptions="Center" VerticalOptions="Center" IsVisible="{Binding IsBusy}"/>
                    </StackLayout>
                </Frame>
            </StackLayout>
        </Grid>
    </ContentPage.Content>
当一个应用程序读取100200500个数据条目时,这个代码工作得非常好。但是当我读取5000个数据条目时,这个应用程序被冻结,想要强制停止。显示数据需要等待2-3分钟。所以我想实现一些延迟加载或无限滚动的逻辑。 这是用于
RemainingItemsThresholdReachedCommand的命令函数,应该为滚动数据编写逻辑:

        async Task ExecuteGetNewPhotos()
        {
            if (IsBusy)
                return;
            try
            {
//some logic here---------->
                IsBusy = true;
                Photos.Clear();
                PhotosModel = await InstagramCloneDataStore.GetAllPhotos();
                if (PhotosModel != null)
                {
                    foreach (var photo in PhotosModel.Photos)
                    {          
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                var msg = ex.Message;
            }
            finally
            {
                IsBusy = false;
            }
        }

我不明白加载或滚动有多慢。有人能帮忙吗?

加载页面时,您应该调用服务加载前X行数据。假设
X=50
——它可以是您想要的任何值

当用户滚动到列表底部时,
CollectionView
将触发
RemainingItemsThresholdReachedCommand
。触发此命令时,您应该从服务中获取下一个X数量的项目,并将其添加到
项目资源中


为此,您的服务需要能够增量加载数据。

您只需提供一个函数,加载下X行数据并将其添加到ObservableCollection中即可。医生解释得很清楚-我真的不明白你到底不明白什么?您的服务是否能够接受允许其返回数据子集的参数?如果不是,那是你需要做的第一件事change@Jason我有一个从API读取的列表。当调用
RemainingItemsThresholdReachedCommand=“{Binding LoadNewPhotosCommand}”
时,如何处理列表?从您的服务加载更多数据,然后将它们添加到ObservableCollection我有一个
ObservableCollection AllPhotos
,其中包含5000个数据条目。并生成另一个
ObservableCollection PhotoSequence
,每次可以从
AllPhotos
中获取50个项目,并绑定到CollectionView的源。这是你的主意吗?不,一次获得5000个项目是让你的应用程序挂起的原因。别这样。相反,使用增量加载将它们分块请求,以提高性能。我必须首先从API获取所有项。这是快的,慢的部分是渲染所有5000个itemsok,然后试着按照你的方式来做。好的,然后试一下你在第一条评论中的建议。
        async Task ExecuteGetAllPhotos()
        {
            if (IsBusy)
                return;      
            try
            {
                IsBusy = true;
                Photos.Clear();
                PhotosModel = await InstagramCloneDataStore.GetAllPhotos();
               if(PhotosModel!=null)
                {
                    foreach (var photo in PhotosModel.Photos)
                    {
                       Photos.Add(photo);                      
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                var msg = ex.Message;
            }
            finally
            {
                IsBusy = false;
            }
        }
        async Task ExecuteGetNewPhotos()
        {
            if (IsBusy)
                return;
            try
            {
//some logic here---------->
                IsBusy = true;
                Photos.Clear();
                PhotosModel = await InstagramCloneDataStore.GetAllPhotos();
                if (PhotosModel != null)
                {
                    foreach (var photo in PhotosModel.Photos)
                    {          
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                var msg = ex.Message;
            }
            finally
            {
                IsBusy = false;
            }
        }