Last active
November 17, 2017 00:07
-
-
Save dotMorten/1b9b00dea1dcd94df45e1bd4ef30c980 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Collections.ObjectModel; | |
using System.Collections.Specialized; | |
using System.Threading.Tasks; | |
using Windows.Foundation; | |
using Windows.UI.Core; | |
using Windows.UI.Xaml.Data; | |
namespace UniversalTestApp | |
{ | |
public class TestClass | |
{ | |
public async void Test() | |
{ | |
IncrementalList<int> list = new IncrementalList<int>(async (count, offset) => | |
{ | |
await Task.Delay(1000); //Simulate delay | |
//Replace this stuff with proper database queries | |
List<int> results = new List<int>(); | |
for (int i = offset; i < offset + count; i++) | |
{ | |
results.Add(i); | |
} | |
return results; | |
}); | |
} | |
} | |
public class IncrementalList<T> : ObservableCollection<T>, ISupportIncrementalLoading | |
{ | |
private Func<int, int, Task<List<T>>> _loadMoreAction; | |
public IncrementalList(IList<T> items, Func<int, int, Task<List<T>>> loadMoreAction) : this(loadMoreAction) | |
{ | |
foreach (var item in items) | |
Items.Add(item); | |
} | |
public IncrementalList(Func<int, int, Task<List<T>>> loadMoreAction) | |
{ | |
if (loadMoreAction == null) | |
throw new ArgumentNullException(nameof(loadMoreAction)); | |
_loadMoreAction = loadMoreAction; | |
} | |
IAsyncOperation<LoadMoreItemsResult> ISupportIncrementalLoading.LoadMoreItemsAsync(uint count) | |
{ | |
return ProcessMoreAsync(count).AsAsyncOperation(); | |
} | |
private async Task<LoadMoreItemsResult> ProcessMoreAsync(uint count) | |
{ | |
var items = await _loadMoreAction((int)count, Count).ConfigureAwait(false); | |
var results = items?.Count ?? 0; | |
HasMoreItems = results >= count; | |
if (results > 0) | |
{ | |
// Ensure we update the list on the UI thread | |
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, | |
() => | |
{ | |
int oldCount = this.Count; | |
foreach (var item in items) | |
base.Items.Add(item); | |
base.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, changedItems: items, startingIndex: oldCount)); | |
base.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs(nameof(Count))); | |
base.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("Items[]")); | |
}); | |
} | |
return new LoadMoreItemsResult() { Count = (uint)results }; | |
} | |
public bool HasMoreItems { get; private set; } = true; | |
} | |
} |
I change:
`IncrementalList<int> list = new IncrementalList<int>(async (count, offset) => {
await Task.Delay(1000);
List<int> results = new List<int>();
for (int i = 0; i < count; i++)
{
results.Add(count);
}
return results;
});`
for:
`IncrementalList<Protocolos> list = new IncrementalList<Protocolos>(async (count, offset) =>
{
// await Task.Delay(1000); //Simulate delay
// Replace this stuff with proper database queries
List<Protocolos> results = new List<Protocolos>();
Task t = Facade.PoblarListaProtocolos(results, tablaProtocolo, textoFiltro, tipoFiltro);
await t;
/*for (int i = 0; i < count; i++)
{
results.Add(count);
}*/
return results;
});`
But not work...
Is the 'results' list getting populated?
On a side-note It might be cleaner if PoblarListaProtocols returns Task<List<Protocols>>
instead of just Task.
List<Protocols> results = await Facade.PoblarListaProtocolos(tablaProtocolo, textoFiltro, tipoFiltro);
Also define 'not work'. I'm terrible at guessing
Just realize this condition is also wrong? HasMoreItems = results < count;
Should be HasMoreItems = results == count
Another thing I just noticed: You never use the count
and offset
values that are passed into the delegate. Your query method PoblarListaProtocolos
needs to take these parameters. Ie the two parameters will tell you "get the next 50
items, starting at offset 100
"
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This implementation is a little more complex than needed, but it adds a few extra optimizations: It uses the protected Items collection to add items, which doesn't raise an event for each Add, then raises a single event at the end for all the items.
It also tries to do as much as possible on the background thread, and only update the collection itself on the UI Thread.