-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathPagingViewModel.cs
148 lines (121 loc) · 4.4 KB
/
PagingViewModel.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
namespace MvvmScarletToolkit.Observables
{
/// <summary>
/// ViewModel that adds paging support to <see cref="DomainViewModelListBase{TViewModel}"/>
/// </summary>
/// <typeparam name="TViewModel"></typeparam>
public sealed class PagingViewModel<TViewModel> : ViewModelBase
where TViewModel : class, INotifyPropertyChanged
{
private readonly DomainViewModelListBase<TViewModel> _viewModel;
private bool _disposed;
[Bindable(true, BindingDirection.OneWay)]
public ICommand NextCommand { get; }
[Bindable(true, BindingDirection.OneWay)]
public ICommand PreviousCommand { get; }
[Bindable(true, BindingDirection.OneWay)]
public ICommand FirstCommand { get; }
[Bindable(true, BindingDirection.OneWay)]
public ICommand LastCommand { get; }
[Bindable(true, BindingDirection.OneWay)]
public ReadOnlyObservableCollection<int> PageSizes { get; }
public PagingViewModel(in IScarletCommandBuilder commandBuilder, in DomainViewModelListBase<TViewModel> viewModel, in ReadOnlyObservableCollection<int> pageSizes)
: base(commandBuilder)
{
_viewModel = viewModel ?? throw new ArgumentNullException(nameof(viewModel));
PageSizes = pageSizes ?? throw new ArgumentNullException(nameof(viewModel));
NextCommand = commandBuilder.Create(Next, CanNext)
.WithSingleExecution()
.WithBusyNotification(BusyStack)
.WithCancellation()
.Build();
PreviousCommand = commandBuilder.Create(Previous, CanPrevious)
.WithSingleExecution()
.WithBusyNotification(BusyStack)
.WithCancellation()
.Build();
FirstCommand = commandBuilder.Create(First, CanFirst)
.WithSingleExecution()
.WithBusyNotification(BusyStack)
.WithCancellation()
.Build();
LastCommand = commandBuilder.Create(Last, CanLast)
.WithSingleExecution()
.WithBusyNotification(BusyStack)
.WithCancellation()
.Build();
}
private int GetNext()
{
return (_viewModel.PageIndex + _viewModel.PageSize < _viewModel.Total - _viewModel.PageSize - 1)
? _viewModel.PageIndex + _viewModel.PageSize
: _viewModel.Total;
}
private Task Next(CancellationToken token)
{
return Set(GetNext(), token);
}
private bool CanNext()
{
return _viewModel.CanRefresh() && GetNext() < _viewModel.Total;
}
private int GetPrevious()
{
return (_viewModel.PageIndex - 1 > _viewModel.PageSize)
? _viewModel.PageIndex - 1
: 0;
}
private Task Previous(CancellationToken token)
{
return Set(GetPrevious(), token);
}
private bool CanPrevious()
{
return _viewModel.CanRefresh() && GetPrevious() > 0;
}
private int GetFirst()
{
return 0;
}
private Task First(CancellationToken token)
{
return Set(GetFirst(), token);
}
private bool CanFirst()
{
return _viewModel.CanRefresh() && _viewModel.PageIndex > GetFirst();
}
private int GetLast()
{
return _viewModel.Total - _viewModel.PageSize - 1;
}
private Task Last(CancellationToken token)
{
return Set(GetLast(), token);
}
private bool CanLast()
{
return _viewModel.CanRefresh() && _viewModel.PageIndex < _viewModel.Total;
}
private async Task Set(int index, CancellationToken token)
{
await Dispatcher.Invoke(() => _viewModel.PageIndex = index, token).ConfigureAwait(false);
await _viewModel.Refresh(token).ConfigureAwait(false);
}
protected override void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
base.Dispose(disposing);
_disposed = true;
}
}
}