2012-09-03 14 views
10

Ho implementato una soluzione di virtualizzazione dei dati utilizzando alcune idee da CodePlex e il blog di Bea Stollnitz e il documento di Vincent Da Ven Berhge (stesso collegamento). Tuttavia, avevo bisogno di un approccio diverso, quindi ho deciso di scrivere la mia soluzione.Pattern di richiesta riga DataGrid con virtualizzazione dei dati

Sto utilizzando uno DataGrid per visualizzare circa un milione di righe con questa soluzione. Sto anche usando la virtualizzazione dell'interfaccia utente. La mia soluzione è fattibile, ma ho riscontrato alcuni strani comportamenti in determinate situazioni su come il DataGrid richieda i dati dalla sua origine.

Circa la soluzione

ho finito per scrivere una lista che fa tutto il lavoro pesante. Si tratta di una classe generica denominata VirtualList<T>. Implementa l'interfaccia ICollectionViewFactory, pertanto il meccanismo di creazione della vista di raccolta può creare un'istanza VirtualListCollectionView<T> per includerla. Questa classe eredita da ListCollectionView. Non ho seguito i suggerimenti per scrivere la mia implementazione ICollectionView. Anche l'ereditarietà funziona bene.

Il VirtualList<T> divide l'intero dato in pagine. Ottiene il conteggio totale delle voci e ogni volta che le richieste di una riga DataGrid tramite l'indicizzatore di elenco carica la pagina appropriata o la restituisce dalla cache. Le pagine vengono riciclate all'interno e un DispatcherTimer dispone le pagine non utilizzate in idle time.

modelli di richiesta dati

  • La prima cosa che ho imparato, che VirtualList<T> dovrebbero attuare IList (non generico). In caso contrario, lo ItemsControl lo considererà come un IEnumerable e interrogherà/enumererà tutte le righe. Questo è logico, dal momento che lo DataGrid non è sicuro, quindi non può usare l'interfaccia IList<T>.

  • La riga con indice 0 viene spesso richiesta dal numero DataGrid. Sembra essere usato per la misurazione degli oggetti visivi (secondo lo stack di chiamate). Quindi, ho semplicemente messo in cache questo.

  • Il meccanismo di memorizzazione nella cache all'interno di DataGrid utilizza un modello prevedibile per interrogare le righe che mostra. Prima chiede le righe visibili dall'alto verso il basso (due volte per ogni riga), quindi interroga un paio di righe (a seconda della dimensione dell'area visibile) prima dell'area visibile (inclusa la prima riga visibile) in una discendente ordina così, dal basso verso l'alto. Dopodiché richiede lo stesso numero di righe dopo le righe visibili (inclusa l'ultima riga visibile) dall'alto verso il basso.

    Se gli indici di riga visibili sono 4,5,6. La richiesta di dati sarebbe: 4,4,5,5,6,6,4,3,2,1,6,7,8,9.

    Se la dimensione della pagina è impostata correttamente, posso soddisfare tutte queste richieste dalla pagina corrente e caricata in precedenza.

  • Se CanSelectMultipleItems è True e l'utente seleziona più voci utilizzando il tasto MAIUSC o trascinamento del mouse, il DataGrid enumera tutte le righe dall'inizio della lista alla fine della selezione. Questa enumerazione avviene tramite l'interfaccia IEnumerable indipendentemente dal fatto che sia implementato o meno IList.

  • Se la riga selezionata non è visibile e l'area visibile corrente è "lontana" dalla riga selezionata, a volte DataGrid inizia a richiedere tutti gli elementi, dalla riga selezionata alla fine dell'area visibile. Comprese tutte le righe intermedie che non sono nemmeno visibili. Non riuscivo a capire il modello esatto di questo comportamento. Forse la mia implementazione è la ragione per questo.

Le mie domande

  • Mi chiedo, perché i DataGrid richieste di file non visibili, dal momento che tali file verranno richiesti nuovamente quando diventano visibili?

  • Perché è necessario richiedere ogni riga due o tre volte?

  • Qualcuno può dirmi come rendere DataGrid non utilizzare IEnumerable, ad eccezione della disattivazione della selezione di più elementi?

risposta

5

Ho trovato almeno un modo per ingannare la VirtualList. Puoi leggerlo here.

Se hai trovato un'altra soluzione (che è anche migliore della mia), per favore dimmi!

+0

Sì, in realtà ho finito per fare qualcosa di simile. Ritorna tutti gli oggetti che ho già caricato e nient'altro. Non ha causato problemi da allora. Grazie –

Problemi correlati