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(); } } }