ISupportIncrementalLoading只触发一次。

5

我正在尝试创建一个Win8 Metro参考应用程序,用于虚拟列表。经过一些(非常稀疏的)阅读,我发现支持此功能的推荐方法是通过ISupportIncrementalLoading接口。

我的参考应用程序存在问题,其中LoadMoreItemsAsync方法被调用了一次,但是不再次调用,尽管我的HasmoreItems属性硬编码为返回True。

以下代码应该加载40个项目,然后以后每次加载“x”个项目。实际情况是它加载了前40个项目,然后提示要加载42个以上,然后再也没有被要求去加载。

以下是我的代码中相关的部分:

XAML

<Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
    <ListView ItemsSource="{Binding Items}" Width="800" HorizontalAlignment="Left" Margin="12">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Title}" Foreground="White"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

</Grid>

ViewModel and Support Classes:

public class MainViewModel : ViewModelBase
{

    public MyIncrementalCollection Items { get; set; }

    public MainViewModel()
    {

        Items = new MyIncrementalCollection();



        for (int i = 0; i < 40; i++)
        {
            Items.Add(new MyData {Title = string.Format("Item: {0}", i)});
        }
    }
}

public class MyData
{
    public string Title { get; set; }
}

public class MyIncrementalCollection : ObservableCollection<MyData>, ISupportIncrementalLoading
{
    public bool HasMoreItems
    {
        get
        {
            return true;
        }
    }

    public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
    {
        return
            (IAsyncOperation<LoadMoreItemsResult>)
            AsyncInfo.Run((System.Threading.CancellationToken ct) => LoadDataAsync(count));
    }

    private async Task<LoadMoreItemsResult> LoadDataAsync(uint count)
    {

        for (int i = 0; i < count; i++)
        {
            this.Add(new MyData { Title = string.Format("Item: {0}, {1}", i, System.DateTime.Now) });
        }

        var ret = new LoadMoreItemsResult {Count = count};

        return ret;
    }


}

}

2个回答

2
问题在于您的方法 LoadDataAsync(uint count) 缺少 await 运算符,因此它将同步运行。 我有过类似的问题。当我接收一些库文件夹时,数据虚拟化对我起作用,但当我尝试加载自定义项目集合时,它只被触发一次。

我使用了一个解决方法,不是很优雅,但它起作用。 像这样修改您的 LoadDataAsync 方法:

private async Task<LoadMoreItemsResult> LoadDataAsync(uint count)
{
  Task task = Task.Delay( 1 );
  await task;

  for (int i = 0; i < count; i++)
  {
    Add(new MyData { Title = string.Format("Item: {0}, {1}", i, System.DateTime.Now) });
  }

  return new LoadMoreItemsResult {Count = count};
}

0
UI 只有在需要时才会调用 HasMoreItems。如果它有足够的项目来填充当前可见区域,那么它不会检查更多的项目。如果您开始向列表末尾滚动,则会检查是否有更多的项目(如果有,则调用 LoadMoreItemsAsync)。
另外,您可以简化 LoadMoreItemsAsync 中的代码。
public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
{
    return LoadDataAsync(count).AsAsyncOperation();
}

感谢简化。这里的问题是,随着我滚动,加载只被调用一次。我可以滚动到列表底部,在第一次加载了额外的项目后,它再也不会触发了。 - Robaticus
好的,你的 XAML 是整个视图吗?其他问题可能包括如果你将 ListView 放在 ScrollViewer 中,你将无法获得数据虚拟化触发器(因为它依赖于使用 List Views 内部的 ScrollViewer)。 - Nigel Sampson
这就是全部内容,除了封闭的<Page>标签。在我的异步加载操作中,我是否需要执行任何特定操作来告诉ListView我已经完成加载,以便它不会再次触发?我认为返回LoadMoreItemsResult应该已经足够了。 - Robaticus
你能试一下最初没有加载任何项目吗?我模糊地记得我曾经遇到过类似的问题,而且我相信那就是解决办法。 - wilbur4321

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接