我一直在尝试为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/