using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using OwlCore.Collections.ObjectModel;
using Windows.Foundation;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
namespace OwlCore.WinUI.Collections
{
///
/// An collection that supports incremental loading.
///
/// Code adapted from
/// The held type in the underlying
public class IncrementalLoadingCollection
: SynchronizedObservableCollection, ISupportIncrementalLoading
{
private readonly Func>> _loadMoreItems;
private readonly Action>? _onBatchComplete;
private readonly Action? _onBatchStart;
///
/// How many records to currently skip
///
private int Skip { get; set; }
///
/// The max number of items to get per batch
///
private int Take { get; set; }
///
/// The number of items in the last batch retrieved
///
private int VirtualCount { get; set; }
///
/// Initializes a new instance of the class.
///
/// How many items to take per batch
/// The load more items function
/// The action to fire when the items are done being retrieved.
/// The action to fire when the is called.
public IncrementalLoadingCollection(int take, Func>> loadMoreItems, Action>? onBatchComplete = null, Action? onBatchStart = null)
: base(SynchronizationContext.Current)
{
Take = take;
_loadMoreItems = loadMoreItems;
_onBatchStart = onBatchStart;
_onBatchComplete = onBatchComplete;
VirtualCount = take;
}
///
/// Returns whether there are more items (if the current batch size is equal to the amount retrieved then YES)
///
public bool HasMoreItems => VirtualCount >= Take;
///
/// Loads more items into the collection.
///
///
/// An asynchronous operation that results in the .
public IAsyncOperation LoadMoreItemsAsync(uint count)
{
CoreDispatcher dispatcher = Window.Current.Dispatcher;
_onBatchStart?.Invoke(); // This is the UI thread
return Task.Run(async () =>
{
var result = await _loadMoreItems(Skip);
VirtualCount = result.Count;
Skip += Take;
foreach (T item in result)
Add(item);
await dispatcher.RunAsync(
CoreDispatcherPriority.Normal,
() =>
{
_onBatchComplete?.Invoke(result); // This is the UI thread
});
return new LoadMoreItemsResult
{
Count = (uint)result.Count,
};
})
.AsAsyncOperation();
}
}
}