【发布时间】:2014-03-03 13:44:13
【问题描述】:
我正在使用 ListView 在 XAML-C# 中开发一个 Windows 应用商店应用程序。
每次用户到达列表末尾时,我都想在 ListView 上加载更多项目。
我刚刚阅读了这个讨论Load more items on grid view scroll end,我刚刚阅读了这个例子http://code.msdn.microsoft.com/windowsapps/Data-Binding-7b1d67b5
我尝试实现类似提到的示例: - 一些我的代码
uint nentries = 0;
// Follow method return a int: number of items (entries) between 0 and 20
nentries = await App.EntriesViewModel.LoadEntries(0);
if (nentries != 0)
{
//entries is a GeneratorIncrementalLoadingClass<Entry>
App.EntriesViewModel.entries = new GeneratorIncrementalLoadingClass<Entry>(nentries, count =>
{
//EntriesOc is an observable collection with INotifyPropertyChanged
return App.EntriesViewModel.EntriesOc.ElementAt(count);
});
//entriesCVS is a CollectionViewSource defined into xaml code
entriesCVS.Source = App.EntriesViewModel.entries;
}
}
this.DataContext = null;
this.DataContext = App.EntriesViewModel;
//until here it's works
if (nentries == 20)
{
uint n = 0;
while (nentries % 20 == 0)
{
n = await App.EntriesViewModel.LoadEntries(nentries);
if (n == 0) break; // no more data to load
nentries += n;
App.EntriesViewModel.entries = new GeneratorIncrementalLoadingClass<Entry>(nentries, (count) =>
{
return App.EntriesViewModel.EntriesOc.ElementAt(count);
});
// without the follow line of code the CollectionViewSource doesn't update
// however the list scroll to the top (I want to remove this behaviour)
entriesCVS.Source = App.EntriesViewModel.entries;
}
}
-
IncrementalLoadingBase.cs(与示例相同的文件)
命名空间 MySolution {
public abstract class IncrementalLoadingBase: IList, ISupportIncrementalLoading, INotifyCollectionChanged { public int Add(object value) { throw new NotImplementedException(); } public void Clear() { throw new NotImplementedException(); } public bool Contains(object value) { return _storage.Contains(value); } public int IndexOf(object value) { return _storage.IndexOf(value); } public void Insert(int index, object value) { throw new NotImplementedException(); } public bool IsFixedSize { get { return false; } } public bool IsReadOnly { get { return true; } } public void Remove(object value) { throw new NotImplementedException(); } public void RemoveAt(int index) { throw new NotImplementedException(); } public object this[int index] { get { return _storage[index]; } set { throw new NotImplementedException(); } } public void CopyTo(Array array, int index) { ((IList)_storage).CopyTo(array, index); } public int Count { get { return _storage.Count; } } public bool IsSynchronized { get { return false; } } public object SyncRoot { get { throw new NotImplementedException(); } } public IEnumerator GetEnumerator() { return _storage.GetEnumerator(); } public bool HasMoreItems { get { return HasMoreItemsOverride(); } } public Windows.Foundation.IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count) { if (_busy) { throw new InvalidOperationException("Only one operation in flight at a time"); } _busy = true; return AsyncInfo.Run((c) => LoadMoreItemsAsync(c, count)); } public event NotifyCollectionChangedEventHandler CollectionChanged; async Task<LoadMoreItemsResult> LoadMoreItemsAsync(CancellationToken c, uint count) { try { var items = await LoadMoreItemsOverrideAsync(c, count); var baseIndex = _storage.Count; _storage.AddRange(items); // Now notify of the new items NotifyOfInsertedItems(baseIndex, items.Count); return new LoadMoreItemsResult { Count = (uint)items.Count }; } finally { _busy = false; } } void NotifyOfInsertedItems(int baseIndex, int count) { if (CollectionChanged == null) { return; } for (int i = 0; i < count; i++) { var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, _storage[i + baseIndex], i + baseIndex); CollectionChanged(this, args); } } protected abstract Task<IList<object>>LoadMoreItemsOverrideAsync(CancellationToken c, uint count); protected abstract bool HasMoreItemsOverride(); List<object> _storage = new List<object>(); bool _busy = false; }}
GeneratorIncrementalLoadingClass.cs(与示例相同的文件)
namespace MySolution{公共类 GeneratorIncrementalLoadingClass: 增量加载基础
{
public GeneratorIncrementalLoadingClass(uint maxCount, Func<int, T> generator)
{
_generator = generator;
_maxCount = maxCount;
}
protected async override Task<IList<object>> LoadMoreItemsOverrideAsync(System.Threading.CancellationToken c, uint count)
{
uint toGenerate = System.Math.Min(count, _maxCount - _count);
// Wait for work
await Task.Delay(10);
// This code simply generates
var values = from j in Enumerable.Range((int)_count, (int)toGenerate)
select (object)_generator(j);
_count += toGenerate;
return values.ToArray();
}
protected override bool HasMoreItemsOverride()
{
return _count < _maxCount;
}
Func<int, T> _generator;
uint _count = 0;
uint _maxCount;
}
}
【问题讨论】:
-
我们需要的一些东西:目前正在发生什么?应该发生什么?是否正在加载项目?物品没有变化吗?
LoadMoreItemsOverrideAsync是否被调用过? -
LoadMoreItemsOverrideAsync 被调用。最后,所有项目都加载完毕。我认为while循环有问题。问题是每次执行 while 循环时列表都会滚动到顶部:如果用户在执行 while 循环时尝试向列表末尾滚动,则滚动位置将重置到列表顶部。跨度>
标签: c# xaml listview windows-store-apps