IncrementalLoadingCollection 在 ListView 中立即加载所有项目

IncrementalLoadingCollection loading all items right away in ListView

我正在用 C# 编写一个 UWP 应用程序。我有一个带有 ListView 的页面,其中包含所有 space 可用。

项目列表很大,所以我使用 IncrementalLoadingCollection 在用户滚动时在 ListView 中逐渐加载项目。

问题是当我启动应用程序时,所有项目都立即加载到 ListView 中。 GetPagedItemsAsync 被一遍又一遍地调用,应用程序崩溃并抛出 Layout cycle detected.

让滚动加载正常工作的唯一方法是将 ListView 或高度固定为某个值。在 ListView 上使用固定高度 GetPagedItemsAsync 仅在初始化时调用一次并且滚动加载按预期工作。

问题是我希望 ListView 填充页面内容,所以我不想将高度设置为特定值。

页面内容

<Grid 
    HorizontalAlignment="Stretch" 
    VerticalAlignment="Stretch">

    <ListView 
        x:Name="channelList" 
        ItemsSource="{x:Bind Channels}"
        DataFetchSize="100" 
        IncrementalLoadingTrigger="Edge" 
        IncrementalLoadingThreshold="5" 
        HorizontalAlignment="Stretch" 
        VerticalAlignment="Stretch">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

</Grid>

页数class

public sealed partial class ChannelsPage : Page
{
    private IncrementalLoadingCollection<ChannelSource, ChannelModel> Channels { get; set; }

    public ChannelsPage()
    {
        this.InitializeComponent();
        Channels = new IncrementalLoadingCollection<ChannelSource, ChannelModel>();
    }

    private class ChannelSource : IIncrementalSource<ChannelModel>
    {
        private int Current { get; set; } = 0;
        private int Limit { get; set; } = 100;
        public async Task<IEnumerable<ChannelModel>> GetPagedItemsAsync(int pageIndex, int pageSize, CancellationToken cancellationToken = default(CancellationToken))
        {
            List<ChannelModel> channels = ChannelModel.List(false, Limit, Current);
            Current += Limit;
            return channels;
        }
    }
}

[已解决] 由于另一个文件中的父项 ScrollViewerListView 正在扩展超出范围。由于其父项目的这种持续扩展,项目正在不停地加载。

解开这个谜团的钥匙是IncrementalLoadingThreshold。简单来说,它表示系统要预加载多少 "pages" 内容。如果您使用 5,系统将确保有 5 倍于控件高度的高度可供查看。尝试将值减小到 1,您应该会看到该方法将被调用一次或两次。甚至更低的值如 0.1 也是可能的。

其次,请确保不要将 ListView 放入任何允许其扩展到任何边界之外的布局控件中。例如,将列表放入具有 RowDefinitionHeight="*"Grid.Row 中将使列表根据需要生成 - 这意味着它将继续加载项目,直到没有更多可用项目为止。

最后,您需要确保在物品用完时注明。如果您 return 一个空的 IEnumerable 来自该方法,这很容易。