@@ -139,52 +139,28 @@ public void KeepResultsExcept(PluginMetadata metadata)
139
139
/// </summary>
140
140
public void AddResults ( List < Result > newRawResults , string resultId )
141
141
{
142
- lock ( _collectionLock )
143
- {
144
- var newResults = NewResults ( newRawResults , resultId ) ;
145
-
146
- // https://social.msdn.microsoft.com/Forums/vstudio/en-US/5ff71969-f183-4744-909d-50f7cd414954/binding-a-tabcontrols-selectedindex-not-working?forum=wpf
147
- // fix selected index flow
148
- var updateTask = Task . Run ( ( ) =>
149
- {
150
- // update UI in one run, so it can avoid UI flickering
151
-
152
- Results . Update ( newResults ) ;
153
- if ( Results . Any ( ) )
154
- SelectedItem = Results [ 0 ] ;
155
- } ) ;
156
- if ( ! updateTask . Wait ( 300 ) )
157
- {
158
- updateTask . Dispose ( ) ;
159
- throw new TimeoutException ( "Update result use too much time." ) ;
160
- }
142
+ var newResults = NewResults ( newRawResults , resultId ) ;
161
143
162
- }
163
-
164
- if ( Visbility != Visibility . Visible && Results . Count > 0 )
165
- {
166
- Margin = new Thickness { Top = 8 } ;
167
- SelectedIndex = 0 ;
168
- Visbility = Visibility . Visible ;
169
- }
170
- else
171
- {
172
- Margin = new Thickness { Top = 0 } ;
173
- Visbility = Visibility . Collapsed ;
174
- }
144
+ UpdateResults ( newResults ) ;
175
145
}
176
146
/// <summary>
177
147
/// To avoid deadlock, this method should not called from main thread
178
148
/// </summary>
179
149
public void AddResults ( IEnumerable < ResultsForUpdate > resultsForUpdates , CancellationToken token )
180
150
{
181
151
var newResults = NewResults ( resultsForUpdates ) ;
152
+
182
153
if ( token . IsCancellationRequested )
183
154
return ;
155
+
156
+ UpdateResults ( newResults , token ) ;
157
+ }
158
+
159
+ private void UpdateResults ( List < ResultViewModel > newResults , CancellationToken token = default )
160
+ {
184
161
lock ( _collectionLock )
185
162
{
186
163
// update UI in one run, so it can avoid UI flickering
187
-
188
164
Results . Update ( newResults , token ) ;
189
165
if ( Results . Any ( ) )
190
166
SelectedItem = Results [ 0 ] ;
@@ -202,7 +178,6 @@ public void AddResults(IEnumerable<ResultsForUpdate> resultsForUpdates, Cancella
202
178
Visbility = Visibility . Collapsed ;
203
179
break ;
204
180
}
205
-
206
181
}
207
182
208
183
private List < ResultViewModel > NewResults ( List < Result > newRawResults , string resultId )
@@ -212,10 +187,10 @@ private List<ResultViewModel> NewResults(List<Result> newRawResults, string resu
212
187
213
188
var results = Results as IEnumerable < ResultViewModel > ;
214
189
215
- var newResults = newRawResults . Select ( r => new ResultViewModel ( r , _settings ) ) . ToList ( ) ;
190
+ var newResults = newRawResults . Select ( r => new ResultViewModel ( r , _settings ) ) ;
216
191
217
192
return results . Where ( r => r . Result . PluginID != resultId )
218
- . Concat ( results . Intersect ( newResults ) . Union ( newResults ) )
193
+ . Concat ( newResults )
219
194
. OrderByDescending ( r => r . Result . Score )
220
195
. ToList ( ) ;
221
196
}
@@ -228,8 +203,7 @@ private List<ResultViewModel> NewResults(IEnumerable<ResultsForUpdate> resultsFo
228
203
var results = Results as IEnumerable < ResultViewModel > ;
229
204
230
205
return results . Where ( r => r != null && ! resultsForUpdates . Any ( u => u . Metadata . ID == r . Result . PluginID ) )
231
- . Concat (
232
- resultsForUpdates . SelectMany ( u => u . Results , ( u , r ) => new ResultViewModel ( r , _settings ) ) )
206
+ . Concat ( resultsForUpdates . SelectMany ( u => u . Results , ( u , r ) => new ResultViewModel ( r , _settings ) ) )
233
207
. OrderByDescending ( rv => rv . Result . Score )
234
208
. ToList ( ) ;
235
209
}
@@ -266,49 +240,50 @@ private static void FormattedTextPropertyChanged(DependencyObject d, DependencyP
266
240
}
267
241
#endregion
268
242
269
- public class ResultCollection : ObservableCollection < ResultViewModel >
243
+ public class ResultCollection : List < ResultViewModel > , INotifyCollectionChanged
270
244
{
271
245
private long editTime = 0 ;
272
246
273
- private bool _suppressNotifying = false ;
274
-
275
247
private CancellationToken _token ;
276
248
277
- protected override void OnCollectionChanged ( NotifyCollectionChangedEventArgs e )
249
+ public event NotifyCollectionChangedEventHandler CollectionChanged ;
250
+
251
+
252
+ protected void OnCollectionChanged ( NotifyCollectionChangedEventArgs e )
278
253
{
279
- if ( ! _suppressNotifying )
280
- {
281
- base . OnCollectionChanged ( e ) ;
282
- }
254
+ CollectionChanged ? . Invoke ( this , e ) ;
283
255
}
284
256
285
- public void BulkAddRange ( IEnumerable < ResultViewModel > resultViews )
257
+ public void BulkAddAll ( List < ResultViewModel > resultViews )
286
258
{
287
- // suppress notifying before adding all element
288
- _suppressNotifying = true ;
289
- foreach ( var item in resultViews )
290
- {
291
- Add ( item ) ;
292
- }
293
- _suppressNotifying = false ;
294
- // manually update event
295
- // wpf use directx / double buffered already, so just reset all won't cause ui flickering
259
+ AddRange ( resultViews ) ;
260
+
261
+ // can return because the list will be cleared next time updated, which include a reset event
296
262
if ( _token . IsCancellationRequested )
297
263
return ;
264
+
265
+ // manually update event
266
+ // wpf use directx / double buffered already, so just reset all won't cause ui flickering
298
267
OnCollectionChanged ( new NotifyCollectionChangedEventArgs ( NotifyCollectionChangedAction . Reset ) ) ;
299
268
}
300
- public void AddRange ( IEnumerable < ResultViewModel > Items )
269
+ private void AddAll ( List < ResultViewModel > Items )
301
270
{
302
- foreach ( var item in Items )
271
+ for ( int i = 0 ; i < Items . Count ; i ++ )
303
272
{
273
+ var item = Items [ i ] ;
304
274
if ( _token . IsCancellationRequested )
305
275
return ;
306
276
Add ( item ) ;
277
+ OnCollectionChanged ( new NotifyCollectionChangedEventArgs ( NotifyCollectionChangedAction . Add , item , i ) ) ;
307
278
}
308
279
}
309
- public void RemoveAll ( )
280
+ public void RemoveAll ( int Capacity = 512 )
310
281
{
311
- ClearItems ( ) ;
282
+ Clear ( ) ;
283
+ if ( this . Capacity > 8000 && Capacity < this . Capacity )
284
+ this . Capacity = Capacity ;
285
+
286
+ OnCollectionChanged ( new NotifyCollectionChangedEventArgs ( NotifyCollectionChangedAction . Reset ) ) ;
312
287
}
313
288
314
289
/// <summary>
@@ -323,15 +298,19 @@ public void Update(List<ResultViewModel> newItems, CancellationToken token = def
323
298
324
299
if ( editTime < 10 || newItems . Count < 30 )
325
300
{
326
- if ( Count != 0 ) ClearItems ( ) ;
327
- AddRange ( newItems ) ;
301
+ if ( Count != 0 ) RemoveAll ( newItems . Count ) ;
302
+ AddAll ( newItems ) ;
328
303
editTime ++ ;
329
304
return ;
330
305
}
331
306
else
332
307
{
333
308
Clear ( ) ;
334
- BulkAddRange ( newItems ) ;
309
+ BulkAddAll ( newItems ) ;
310
+ if ( Capacity > 8000 && newItems . Count < 3000 )
311
+ {
312
+ Capacity = newItems . Count ;
313
+ }
335
314
editTime ++ ;
336
315
}
337
316
}
0 commit comments