2
2
// Roland Pheasant licenses this file to you under the MIT license.
3
3
// See the LICENSE file in the project root for full license information.
4
4
5
+ using System . ComponentModel ;
5
6
using System . Reactive . Disposables ;
6
7
using System . Reactive . Linq ;
7
8
using DynamicData . Cache ;
@@ -30,15 +31,22 @@ public SortAndBind(IObservable<IChangeSet<TObject, TKey>> source,
30
31
SortAndBindOptions options ,
31
32
IList < TObject > target )
32
33
{
34
+ var scheduler = options . Scheduler ;
35
+
33
36
// static one time comparer
34
37
var applicator = new SortApplicator ( _cache , target , comparer , options ) ;
35
38
36
- _sorted = source . Do ( changes =>
39
+ if ( scheduler is not null )
40
+ source = source . ObserveOn ( scheduler ) ;
41
+
42
+ _sorted = source . Select ( ( changes , index ) =>
37
43
{
38
44
// clone to local cache so that we can sort the entire set when threshold is over a certain size.
39
45
_cache . Clone ( changes ) ;
40
46
41
- applicator . ProcessChanges ( changes ) ;
47
+ applicator . ProcessChanges ( changes , index == 0 ) ;
48
+
49
+ return changes ;
42
50
} ) ;
43
51
}
44
52
@@ -48,6 +56,14 @@ public SortAndBind(IObservable<IChangeSet<TObject, TKey>> source,
48
56
IList < TObject > target )
49
57
=> _sorted = Observable . Create < IChangeSet < TObject , TKey > > ( observer =>
50
58
{
59
+ var scheduler = options . Scheduler ;
60
+
61
+ if ( scheduler is not null )
62
+ {
63
+ source = source . ObserveOn ( scheduler ) ;
64
+ comparerChanged = comparerChanged . ObserveOn ( scheduler ) ;
65
+ }
66
+
51
67
var locker = new object ( ) ;
52
68
SortApplicator ? sortApplicator = null ;
53
69
@@ -61,14 +77,17 @@ public SortAndBind(IObservable<IChangeSet<TObject, TKey>> source,
61
77
62
78
// Listen to changes and apply the sorting
63
79
var subscriber = source . Synchronize ( locker )
64
- . Do ( changes =>
80
+ . Select ( ( changes , index ) =>
65
81
{
66
82
_cache . Clone ( changes ) ;
67
83
68
84
// the sort applicator will be null until the comparer change observable fires.
69
85
if ( sortApplicator is not null )
70
- sortApplicator . ProcessChanges ( changes ) ;
71
- } ) . SubscribeSafe ( observer ) ;
86
+ sortApplicator . ProcessChanges ( changes , index == 0 ) ;
87
+
88
+ return changes ;
89
+ } )
90
+ . SubscribeSafe ( observer ) ;
72
91
73
92
return new CompositeDisposable ( latestComparer , subscriber ) ;
74
93
} ) ;
@@ -92,10 +111,12 @@ public void ApplySort()
92
111
}
93
112
94
113
// apply sorting as a side effect of the observable stream.
95
- public void ProcessChanges ( IChangeSet < TObject , TKey > changeSet )
114
+ public void ProcessChanges ( IChangeSet < TObject , TKey > changeSet , bool isFirstTimeLoad )
96
115
{
116
+ var forceReset = isFirstTimeLoad && options . ResetOnFirstTimeLoad ;
117
+
97
118
// apply sorted changes to the target collection
98
- if ( options . ResetThreshold > 0 && options . ResetThreshold < changeSet . Count )
119
+ if ( forceReset || ( options . ResetThreshold > 0 && options . ResetThreshold < changeSet . Count ) )
99
120
{
100
121
Reset ( cache . Items . OrderBy ( t => t , comparer ) , true ) ;
101
122
}
@@ -122,6 +143,15 @@ private void Reset(IEnumerable<TObject> sorted, bool fireReset)
122
143
observableCollectionExtended . Load ( sorted ) ;
123
144
}
124
145
}
146
+ else if ( fireReset && target is BindingList < TObject > bindingList )
147
+ {
148
+ // suspend count as it can result in a flood of binding updates.
149
+ using ( new BindingListEventsSuspender < TObject > ( bindingList ) )
150
+ {
151
+ target . Clear ( ) ;
152
+ target . AddRange ( sorted ) ;
153
+ }
154
+ }
125
155
else
126
156
{
127
157
target . Clear ( ) ;
0 commit comments