我一直在尝试为ISupportIncrementalLoading实现ObservableCollection接口。我的实现在大多数情况下都有效,但是在不确定的情况下它的表现却很奇怪。这是我的IncrementalCollection类代码。

public class IncrementalCollection<T> : ObservableCollection<T>, ISupportIncrementalLoading
{
    private bool hasMoreItems;
    private int currentPage;
    private string filter;

    private Func<string, int, Task<IList<T>>> func;
    Action onLoadingStarts;
    Action onLoadingEnds;

    public IncrementalCollection(Func<string, int, Task<IList<T>>> func, Action onLoadingStarts, Action onLoadingEnds)
    {
        this.func = func;
        this.hasMoreItems = true;

        this.onLoadingStarts = onLoadingStarts;
        this.onLoadingEnds = onLoadingEnds;
    }

    public void ResetCollection(string filter)
    {
        currentPage = 0;
        this.filter = filter;
        this.Clear();
    }

    public bool HasMoreItems
    {
        get { return hasMoreItems; }
    }

    public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count)
    {
        return DoLoadMoreItemsAsync(count).AsAsyncOperation<LoadMoreItemsResult>();
    }

    private async Task<LoadMoreItemsResult> DoLoadMoreItemsAsync(uint count)
    {
        onLoadingStarts();
        var result = await func(this.filter, ++this.currentPage);
        if (result == null || result.Count == 0)
        {
            hasMoreItems = false;
        }
        else
        {
            foreach (T item in result)
                this.Add(item);
        }

        onLoadingEnds();
        return new LoadMoreItemsResult() { Count = result == null ? 0 : (uint)result.Count };
    }
}


第一个奇怪的行为是在页面加载时发生的,LoadMoreItemsAsync函数有时被调用一次,通常被调用两次,有时被调用两次以上。这很奇怪,因为一个调用足以将足够的项目添加到集合中。我什至尝试提取更多数据(2-3次),但行为仍在继续。 IncrementalCollection对象的初始化位置可能存在问题。看起来,加载页面所需的时间越长,对LoadMoreItemsAsync函数的调用就越多。我在这样的NavigationHelper_LoadState函数中创建集合。

_users = new IncrementalCollection<User>((filter, page) => _dataService.GetUserList(url, filter, null, page), onLoadingStarts, onLoadingEnds);


第二个奇怪的行为是关于缓存的,尽管我已经添加了

this.NavigationCacheMode = NavigationCacheMode.Disabled;


到每个页面构造函数,并且还更改了NavigationHelper而不在后退导航中保存pageState。感觉就像Web请求被缓存了,因为很难在该时间内返回响应。

public void OnNavigatedFrom(NavigationEventArgs e)
{
    if (e.NavigationMode == NavigationMode.Back)
        return;

    var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
    var pageState = new Dictionary<String, Object>();
    if (this.SaveState != null)
    {
        this.SaveState(this, new SaveStateEventArgs(pageState));
    }
    frameState[_pageKey] = pageState;
}


感谢您提供有关这些奇怪行为的任何帮助。

也有关于ISupportIncrementalLoading界面的好教程,可以解释LoadMoreItemsAsync触发条件。我正在尝试修改WrapPanel实现,但不知道从哪里开始,因为我不知道它在寻找什么。这可能与ItemHeight有关,但具体信息还是更好的。

提前致谢。

最佳答案

ISupportIncrementalLoading界面中似乎存在一个错误。通过在此处Create a ListView with LoadMoreItemsAsync on end of scroll应用解决方案解决了多请求问题。

我将foreach循环包装在Task.WhenAll调用内。

await Task.WhenAll(Task.Delay(50), Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
    foreach (T item in result)
        this.Add(item);
}).AsTask());

关于c# - LoadMoreItemsAsync称为可变时间,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27676607/

10-10 18:15