1

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;
    }
}

今、ロードされたすべてのアイテムをクリアし、別の URL から新しいデータをロードしようとしています (ユーザーは「カテゴリ」を切り替えることができるはずです)。

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();
    }

しかし、多くの場合、結果には古い URL からの結果が取り込まれます (おそらく非同期クエリのため)、または hasMoreItems が false に設定されているか、増分読み込みが機能しなくなります。

以前のアイテムをすべて取り除き、古い URL からロードしているすべてのタスクを停止し、新しい URL からのみロードを開始する適切な方法は何ですか?

4

1 に答える 1

0

別の引数 (新しい uri、カテゴリなど) を使用して 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 に通知する必要があります。

于 2015-09-03T08:15:11.353 に答える