我一直在努力为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
,但具体信息仍然更好。
提前致谢。
答案 0 :(得分:0)
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());