WP8.1 Universal:从ISupportIncrementalLoading中正确取消并重新启动LoadMoreItemsAsync

时间:2015-08-29 21:44:26

标签: windows-phone-8.1 windows-store-apps endlessscroll

为了在我的WP8.1通用应用程序中进行无休止的滚动,我实现了ISupportIncrementalLoading,并且我使用结果绑定到我的ListView。使用此代码可以正常工作:

public sealed class IncrementalLoadingCollection<T, I> : ObservableCollection<I>, ISupportIncrementalLoading
    where T : IIncrementalSource<I>, new()
{
    private int currentPage;
    private bool hasMoreItems;
    private int itemsPerPage;
    private T source;

    public IncrementalLoadingCollection(int itemsPerPage = 10)
    {
        this.source = new T();
        this.itemsPerPage = itemsPerPage;
        this.hasMoreItems = true;
    }

    public bool HasMoreItems
    {
        get { return this.hasMoreItems; }
    }

    public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
    {
        return AsyncInfo.Run(c => LoadMoreItemsAsync(c, count));
    }

    private async Task<LoadMoreItemsResult> LoadMoreItemsAsync(CancellationToken cancellationToken, uint count)
    {
        var dispatcher = Window.Current.Dispatcher;

        var task = await Task.Run<LoadMoreItemsResult>(
            async () =>
            {
                if (Count == 0 && this.currentPage > 0)
                {
                    this.currentPage = 0; // this was cleared
                }
                uint resultCount = 0;

                var result = await this.source.GetPagedItems(cancellationToken, this.currentPage, this.itemsPerPage);

                this.currentPage++;

                if (result == null || !result.Any())
                {
                    this.hasMoreItems = false;
                }
                else
                {
                    resultCount = (uint)result.Count();

                    await dispatcher.RunAsync(
                        CoreDispatcherPriority.Normal,
                        () =>
                        {
                            foreach (I item in result)
                            {
                                Add(item);
                            }
                        });
                }

                return new LoadMoreItemsResult { Count = resultCount };
            }, cancellationToken);
        return task;
    }
}

现在我正在尝试清除所有已加载的项目,并使用以下代码从其他网址加载新数据(用户应该可以切换“类别”):

public void ClearAndSetNewUrl(string newUrl)
    {
        if (this.LoadMoreItemsAsync((uint) this.itemsPerPage).Status == AsyncStatus.Started)
        {
            this.LoadMoreItemsAsync((uint) this.itemsPerPage).Cancel();
        }
        this.source.SetUrl(newUrl);
        this.hasMoreItems = true;
        base.ClearItems();
    }

但结果通常填充旧网址的结果(可能是因为异步查询)或者hasMoreItems设置为false和/或增量加载停止工作。

什么是摆脱所有先前项目的正确方法,停止从旧网址加载的所有任务并开始仅从新网址加载?

1 个答案:

答案 0 :(得分:0)

使用另一个参数(new uri,category等)创建IncrementalLoadingCollection的新实例,并将其重置为ListView的ItemsSource。所以它应该有所帮助。

<强>更新

public class MyViewModel : PropertyChangeBase
{
      public ThemeEventsDataSource ItemsSource
        {
            get { return _itemsSource; }
            set
            {
                if (Equals(value, _itemsSource)) return;
                _itemsSource = value;
                NotifyOfPropertyChange();
            }
        }
}

public class ThemeEventsDataSource : ObservableCollection<ThemeEventViewModel>, ISupportIncrementalLoading
    {
        public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
        {
            return AsyncInfo.Run(c => LoadMoreThemeEventsAsync(count));
        }

         private async Task<LoadMoreItemsResult> LoadMoreThemeEventsAsync(uint count)
{
//TODO: your code for Getting data
this.Add(...);
return new LoadMoreItemsResult { Count = (uint)items.Length };
}
    }

因此,当您需要更改上下文(更改了uri,更改过滤器等)时,您应该使用指定的参数创建新的ThemeEventsDataSource并通知UI。