2010-03-17 8 views
5

Possiedo un oggetto ItemsControl (non virtualizzato) che associa la sua risorsa ItemsSource a una raccolta ObeservableCollection di ViewModel. Ora, una volta caricate le istanze del modello di quantità elevate, tutti i componenti ViewModel devono essere aggiunti a ObservableCollection. Come posso aggiungere una grande quantità di ViewModels senza far cadere il thread dell'interfaccia utente?ItemsControl.ItemsSource Prestazioni MVVM

Suppongo che il thread dell'interfaccia utente si blocca perché ogni volta che viene aggiunto un nuovo elemento, ItemsControl deve aggiornarsi e ripetere il layout più e più volte.

  • Devo sospendere l'associazione aggiungere tutti gli articoli e quindi riprendere? Se é cosi, come?
  • Dovrei ignorare l'ObservableCollection di implementare un AddRange in modo che solo 1 CollectionChanged evento viene generato per l'aggiunta di più macchine? O in alternativa basta sostituire l'intera collezione?
  • O è meglio aggiungere separatamente ogni articolo e chiamare Dispatcher.Invoke per ogni articolo separatamente? Quindi avrei sbloccato spesso .

Come gestite elenchi dinamici di grandi dimensioni che non possono essere virtualizzati?

+0

Cosa stai usando? WPF/Silverlight? WinForms? Qualcos'altro? – slugster

+0

Dovrebbe essere ovvio che non è Windows Form perché nessuna delle classi citate esiste nei moduli di Windows. – bitbonk

+0

c'è qualche ragione specifica per cui il tuo itemscontrol non può usare la virtualizzazione dell'interfaccia utente? –

risposta

10

È possibile creare una una classe derivata da ObservableCollection che permette di sospendere temporaneamente CollectionChanged eventi come questo:

public class SuspendableObservableCollection : ObservableCollection 
{ 
    private bool suspended; 

    public bool Suspended 
    { 
     get 
     { 
      return this.suspended; 
     } 
     set 
     { 
      this.suspended = value; 
      OnCollectionChanged(new NotifyCollectionChangedEventArgs(
       NotifyCollectionChangedAction.Reset)); 
     } 
    } 

    protected override void OnCollectionChanged(
     NotifyCollectionChangedEventArgs args) 
    { 
     if (!Suspended) 
     { 
      base.OnCollectionChanged(args); 
     } 
    } 
} 
+0

La mia domanda è più rivolta a come posso migliorare le prestazioni non come implementare una tale raccolta. Inoltre, se sospendo temporaneamente eventi come suggerisci che ItemsControl visualizzerà lo stato sbagliato dopo la ripresa della sospensione. E se poi viene sollevato un nuovo evento CollectionChanged, verrà comunque visualizzato lo stato errato perché non ha ottenuto tutte le modifiche apportate alla raccolta mentre era sospeso. – bitbonk

+0

1) Non implementare tale raccolta consente di migliorare le prestazioni? 2) Ho aggiunto un evento di reset per risolvere il problema che hai descritto. –

+0

Sembra che questo non migliori le prestazioni. Probabilmente perché tze ItemsControl ha bisogno di generare molti Controlli oggetto contemporaneamente. Quindi immagino che l'approccio migliore sarebbe quello di aggiungere alcuni elementi separatamente usando (Begin) Invoke più volte. – bitbonk

0
<ItemsControl IsAsync="True" ... /> 
+0

Probabilmente intendevi ''. 'ItemsControl' non ha questa proprietà. Questa proprietà dovrebbe essere usata con parsimonia: "non ci dovrebbero essere molti scenari in cui è necessario utilizzare la proprietà IsAsync. Le linee guida di .NET raccomandano di definire le proprietà che sono ordini di grandezza più lenti di quanto sarebbe un set di campi". – bitbonk

+0

ah Pensavo che ogni selettore abbia la proprietà IsAsync. Quando si carica una finestra che carica molti dati in modo non asincrono si ottiene una finestra nera o si blocca (come nel mio caso usando IsAsync = True adesso). Si consiglia quindi IsAsync! – Elisabeth

+0

Se stai suggerendo di fare ' 'che non fa il trucco.' IsAsnyc' funziona solo quando lo stesso DataSource non è disponibile immediatamente o prende Nel mio caso il DataSource è subito disponibile ma contiene solo molti articoli. Leggi qui per maggiori dettagli sul problema: http://goo.gl/BwA1 – bitbonk