Создать ListView с помощью LoadMoreItemsAsync в конце прокрутки
у меня естьListView
в моем приложении Windows Phone 8.1, и я могу получить что-то вроде 1000 или более результатов, поэтому мне нужно реализовывать функцию «Загрузить больше» каждый раз, когда прокрутка достигает дна, или какой-то другой логический и естественный способ инициировать добавление большего количества элементов в список ,
Я обнаружил, чтоListView
имеет поддержку дляISupportIncrementalLoading
и нашел эту реализацию:https://marcominerva.wordpress.com/2013/05/22/implementing-the-isupportincrementalloading-interface-in-a-window-store-app/ Это было лучшее решение, которое я нашел, так как оно не указывает тип, то есть оно является общим.
Моя проблема с этим решением заключается в том, что когда ListView загружен,LoadMoreItemsAsync
выполняется все необходимое время, пока не будут получены все результаты, а это означает, что Load More не запускается пользователем. Я не уверен, что делаетLoadMoreItemsAsync
триггер, но что-то не так, потому что предполагается, что это происходит, когда я открываю страницу и загружаю все элементы на месте, без каких-либо действий или прокрутки. Вот реализация:IncrementalLoadingCollection.cs
public interface IIncrementalSource<T> {
Task<IEnumerable<T>> GetPagedItems(int pageIndex, int pageSize);
void SetType(int type);
}
public class IncrementalLoadingCollection<T, I> : ObservableCollection<I>, ISupportIncrementalLoading where T : IIncrementalSource<I>, new() {
private T source;
private int itemsPerPage;
private bool hasMoreItems;
private int currentPage;
public IncrementalLoadingCollection(int type, int itemsPerPage = 10) {
this.source = new T();
this.source.SetType(type);
this.itemsPerPage = itemsPerPage;
this.hasMoreItems = true;
}
public bool HasMoreItems {
get { return hasMoreItems; }
}
public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count) {
var dispatcher = Window.Current.Dispatcher;
return Task.Run<LoadMoreItemsResult>(
async () => {
uint resultCount = 0;
var result = await source.GetPagedItems(currentPage++, itemsPerPage);
if(result == null || result.Count() == 0) {
hasMoreItems = false;
}
else {
resultCount = (uint)result.Count();
await dispatcher.RunAsync(
CoreDispatcherPriority.Normal,
() => {
foreach(I item in result)
this.Add(item);
});
}
return new LoadMoreItemsResult() { Count = resultCount };
}).AsAsyncOperation<LoadMoreItemsResult>();
}
}
ВотPersonModelSource.cs
public class DatabaseNotificationModelSource : IIncrementalSource<DatabaseNotificationModel> {
private ObservableCollection<DatabaseNotificationModel> notifications;
private int _type = "";
public DatabaseNotificationModelSource() {
//
}
public void SetType(int type) {
_type = type;
}
public async Task<IEnumerable<DatabaseNotificationModel>> GetPagedItems(int pageIndex, int pageSize) {
if(notifications == null) {
notifications = new ObservableCollection<DatabaseNotificationModel>();
notifications = await DatabaseService.GetNotifications(_type);
}
return await Task.Run<IEnumerable<DatabaseNotificationModel>>(() => {
var result = (from p in notifications select p).Skip(pageIndex * pageSize).Take(pageSize);
return result;
});
}
}
Я немного его изменил, потому что вызов моей базы данных является асинхронным, и это был единственный способ, который я нашел, чтобы убедиться, что я могу дождаться запроса перед заполнением коллекции.
И по моемуDatabaseNotificationViewModel.cs
IncrementalNotificationsList = new IncrementalLoadingCollection<DatabaseNotificationModelSource, DatabaseNotificationModel>(type);
Все отлично работает, кроме не совсем обычного «Load More». Что не так в моем коде?