@@ -139,52 +139,28 @@ public void KeepResultsExcept(PluginMetadata metadata)
139139 /// </summary>
140140 public void AddResults ( List < Result > newRawResults , string resultId )
141141 {
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 ) ;
161143
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 ) ;
175145 }
176146 /// <summary>
177147 /// To avoid deadlock, this method should not called from main thread
178148 /// </summary>
179149 public void AddResults ( IEnumerable < ResultsForUpdate > resultsForUpdates , CancellationToken token )
180150 {
181151 var newResults = NewResults ( resultsForUpdates ) ;
152+
182153 if ( token . IsCancellationRequested )
183154 return ;
155+
156+ UpdateResults ( newResults , token ) ;
157+ }
158+
159+ private void UpdateResults ( List < ResultViewModel > newResults , CancellationToken token = default )
160+ {
184161 lock ( _collectionLock )
185162 {
186163 // update UI in one run, so it can avoid UI flickering
187-
188164 Results . Update ( newResults , token ) ;
189165 if ( Results . Any ( ) )
190166 SelectedItem = Results [ 0 ] ;
@@ -202,7 +178,6 @@ public void AddResults(IEnumerable<ResultsForUpdate> resultsForUpdates, Cancella
202178 Visbility = Visibility . Collapsed ;
203179 break ;
204180 }
205-
206181 }
207182
208183 private List < ResultViewModel > NewResults ( List < Result > newRawResults , string resultId )
@@ -212,10 +187,10 @@ private List<ResultViewModel> NewResults(List<Result> newRawResults, string resu
212187
213188 var results = Results as IEnumerable < ResultViewModel > ;
214189
215- var newResults = newRawResults . Select ( r => new ResultViewModel ( r , _settings ) ) . ToList ( ) ;
190+ var newResults = newRawResults . Select ( r => new ResultViewModel ( r , _settings ) ) ;
216191
217192 return results . Where ( r => r . Result . PluginID != resultId )
218- . Concat ( results . Intersect ( newResults ) . Union ( newResults ) )
193+ . Concat ( newResults )
219194 . OrderByDescending ( r => r . Result . Score )
220195 . ToList ( ) ;
221196 }
@@ -228,8 +203,7 @@ private List<ResultViewModel> NewResults(IEnumerable<ResultsForUpdate> resultsFo
228203 var results = Results as IEnumerable < ResultViewModel > ;
229204
230205 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 ) ) )
233207 . OrderByDescending ( rv => rv . Result . Score )
234208 . ToList ( ) ;
235209 }
@@ -266,49 +240,50 @@ private static void FormattedTextPropertyChanged(DependencyObject d, DependencyP
266240 }
267241 #endregion
268242
269- public class ResultCollection : ObservableCollection < ResultViewModel >
243+ public class ResultCollection : List < ResultViewModel > , INotifyCollectionChanged
270244 {
271245 private long editTime = 0 ;
272246
273- private bool _suppressNotifying = false ;
274-
275247 private CancellationToken _token ;
276248
277- protected override void OnCollectionChanged ( NotifyCollectionChangedEventArgs e )
249+ public event NotifyCollectionChangedEventHandler CollectionChanged ;
250+
251+
252+ protected void OnCollectionChanged ( NotifyCollectionChangedEventArgs e )
278253 {
279- if ( ! _suppressNotifying )
280- {
281- base . OnCollectionChanged ( e ) ;
282- }
254+ CollectionChanged ? . Invoke ( this , e ) ;
283255 }
284256
285- public void BulkAddRange ( IEnumerable < ResultViewModel > resultViews )
257+ public void BulkAddAll ( List < ResultViewModel > resultViews )
286258 {
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
296262 if ( _token . IsCancellationRequested )
297263 return ;
264+
265+ // manually update event
266+ // wpf use directx / double buffered already, so just reset all won't cause ui flickering
298267 OnCollectionChanged ( new NotifyCollectionChangedEventArgs ( NotifyCollectionChangedAction . Reset ) ) ;
299268 }
300- public void AddRange ( IEnumerable < ResultViewModel > Items )
269+ private void AddAll ( List < ResultViewModel > Items )
301270 {
302- foreach ( var item in Items )
271+ for ( int i = 0 ; i < Items . Count ; i ++ )
303272 {
273+ var item = Items [ i ] ;
304274 if ( _token . IsCancellationRequested )
305275 return ;
306276 Add ( item ) ;
277+ OnCollectionChanged ( new NotifyCollectionChangedEventArgs ( NotifyCollectionChangedAction . Add , item , i ) ) ;
307278 }
308279 }
309- public void RemoveAll ( )
280+ public void RemoveAll ( int Capacity = 512 )
310281 {
311- ClearItems ( ) ;
282+ Clear ( ) ;
283+ if ( this . Capacity > 8000 && Capacity < this . Capacity )
284+ this . Capacity = Capacity ;
285+
286+ OnCollectionChanged ( new NotifyCollectionChangedEventArgs ( NotifyCollectionChangedAction . Reset ) ) ;
312287 }
313288
314289 /// <summary>
@@ -323,15 +298,19 @@ public void Update(List<ResultViewModel> newItems, CancellationToken token = def
323298
324299 if ( editTime < 10 || newItems . Count < 30 )
325300 {
326- if ( Count != 0 ) ClearItems ( ) ;
327- AddRange ( newItems ) ;
301+ if ( Count != 0 ) RemoveAll ( newItems . Count ) ;
302+ AddAll ( newItems ) ;
328303 editTime ++ ;
329304 return ;
330305 }
331306 else
332307 {
333308 Clear ( ) ;
334- BulkAddRange ( newItems ) ;
309+ BulkAddAll ( newItems ) ;
310+ if ( Capacity > 8000 && newItems . Count < 3000 )
311+ {
312+ Capacity = newItems . Count ;
313+ }
335314 editTime ++ ;
336315 }
337316 }
0 commit comments