我使用ListView在Windows應用商店的XAML-C#中開發。使用ListView加載更多項目(Windows 8.1)
我想每次用戶到達列表的末尾時在ListView上加載更多的項目。
我剛剛看了這個討論Load more items on grid view scroll end和我剛剛看了這個例子http://code.msdn.microsoft.com/windowsapps/Data-Binding-7b1d67b5
我試圖執行像提到的例子: - 一些mycode的的
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(同示例的文件)
namespa CE 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: IncrementalLoadingBase
{
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循環時滾動到列表的末尾,則將滾動位置重置爲列表的頂部。 –