/
PagedDataViewer.cs
75 lines (63 loc) · 2.9 KB
/
PagedDataViewer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System;
using System.Collections.ObjectModel;
using System.Reactive.Linq;
using DynamicData;
using DynamicData.Binding;
using DynamicData.PLinq;
using Trader.Client.Infrastructure;
using Trader.Domain.Infrastucture;
using Trader.Domain.Model;
using Trader.Domain.Services;
namespace Trader.Client.Views
{
public class PagedDataViewer : AbstractNotifyPropertyChanged, IDisposable
{
private readonly IDisposable _cleanUp;
private readonly ReadOnlyObservableCollection<TradeProxy> _data;
private string _searchText;
public PagedDataViewer(ITradeService tradeService, ISchedulerProvider schedulerProvider)
{
//build observable predicate from search text
var filter = this.WhenValueChanged(t => t.SearchText)
.Throttle(TimeSpan.FromMilliseconds(250))
.Select(BuildFilter);
//build observable sort comparer
var sort = SortParameters.WhenValueChanged(t => t.SelectedItem)
.Select(prop => prop.Comparer)
.ObserveOn(schedulerProvider.Background);
var pager = PageParameters.WhenChanged(vm=>vm.PageSize,vm=>vm.CurrentPage, (_,size, pge) => new PageRequest(pge, size))
.StartWith(new PageRequest(1, 25))
.DistinctUntilChanged()
.Sample(TimeSpan.FromMilliseconds(100));
// filter, sort, page and bind to observable collection
_cleanUp = tradeService.All.Connect()
.Filter(filter) // apply user filter
.Transform(trade => new TradeProxy(trade), new ParallelisationOptions(ParallelType.Ordered, 5))
.Sort(sort, SortOptimisations.ComparesImmutableValuesOnly)
.Page(pager)
.ObserveOn(schedulerProvider.MainThread)
.Do(changes => PageParameters.Update(changes.Response))
.Bind(out _data) // update observable collection bindings
.DisposeMany() // dispose when no longer required
.Subscribe();
}
private static Func<Trade, bool> BuildFilter(string searchText)
{
if (string.IsNullOrEmpty(searchText)) return trade => true;
return t => t.CurrencyPair.Contains(searchText, StringComparison.OrdinalIgnoreCase) ||
t.Customer.Contains(searchText, StringComparison.OrdinalIgnoreCase);
}
public string SearchText
{
get => _searchText;
set => SetAndRaise(ref _searchText, value);
}
public ReadOnlyObservableCollection<TradeProxy> Data => _data;
public PageParameterData PageParameters { get;} = new PageParameterData(1,25);
public SortParameterData SortParameters { get; } = new SortParameterData();
public void Dispose()
{
_cleanUp.Dispose();
}
}
}