2012-03-18 4 views
10

Ho un'applicazione SL con molti DataGrid (da Silverlight Toolkit), ognuno con la propria vista. Se vengono aperti più DataGrid, la modifica tra le viste (ad esempio TabItems) richiede molto tempo (alcuni secondi) e congela l'intera applicazione (thread dell'interfaccia utente).Prestazioni Silverlight con molti controlli caricati

Più DataGrid vengono caricati, maggiore è il tempo richiesto. Questi DataGrid che rallentano la variazione dell'interfaccia utente potrebbero trovarsi in altri punti dell'app e non essere nemmeno visibili in quel momento. Ma una volta aperti (e caricati con i dati), rallentano la visualizzazione di altri DataGrid. Si noti che i DataGrid NON sono disposti e quindi ricreati di nuovo, rimangono ancora in memoria, solo il loro controllo genitore è nascosto e visibile di nuovo.

Ho profilato l'applicazione. Mostra che la funzione SetValue di agcore.dll è il collo di bottiglia. Sfortunatamente, i simboli di debug non sono disponibili per questa libreria nativa di Silverlight responsabile del disegno.

Il problema non è nel controllo DataGrid. Ho provato a sostituirlo con la griglia di XCeed e le prestazioni quando si cambiano le viste sono ancora peggiori.

Avete qualche idea su come risolvere questo problema? Perché più controlli aperti rallentano altri controlli?

ho creato un esempio che illustra il problema: VS solution, live demo

UPDATE: Uso VS11 profilatore sul campione suggerisce che il problema poteva essere MeasureOverride essere chiamato molte volte (per ogni DataGridCell, I indovina). Ma ancora, perché è più lento come più controlli vengono caricati altrove? C'è un modo per migliorare le prestazioni?

UPDATE 2: Devo dire che non uso TabControl nella mia particolare applicazione. Uso Caliburn.Micro e ContentControl per mostrare ViewModel attualmente attivo. Ma lo stesso problema è con TabControl, quindi l'ho usato per descrivere il problema principale.

+2

Vedi la discussione qui (la punta circa TabControl), è potrebbe aiutare: http://stackoverflow.com/questions/1389769/wpf-virtualizingstackpanel-for-increased-performance – Phil

+0

In realtà, nella mia applicazione originale, utilizzo Caliburn.Micro (MVVM framework) così invece di un TabControl, ho un ContentControl associato a ViewModel attualmente attivo (e quindi alla sua vista). Tuttavia, controllerò la discussione e ti farò sapere. Grazie! – gius

+0

filedropper 404'ed –

risposta

5

Così, ho seguito l'idea di creare un controllo personalizzato e qui è il risultato: http://www.baud.cz/blog/fast-switching-between-viewmodels-in-caliburn.micro.

Collegamenti rapidi ad applicazioni demo MVVM: Original e Fixed

+0

+1. Questo è quello che abbiamo finito per fare in un progetto. Abbiamo avuto la stessa configurazione 'TabControl' con perdita di visualizzazione e abbiamo utilizzato anche Caliburn. E la soluzione era di memorizzare nella cache e restituire le viste memorizzate nella cache con 'IViewAware.GetView' – nemesv

+1

AFAIK, IViewAware.GetView in Caliburn.Micro memorizza già le viste nella cache. Penso che si possa dire cambiando le viste in TabControl dove persiste la posizione della barra di scorrimento (questo non è salvato nella VM). – gius

0

Abbiamo sperimentato qualcosa di simile a questo, stavamo caricando molti controlli utente pesanti carichi di controllo in modo dinamico e più si rendevano più lenta sembrava l'app. Per quanto possa sembrare assurdo, quando impostiamo la radice di layout di ciascun controllo su un controllo Border, i problemi di prestazioni sono diminuiti in modo significativo in quanto il sistema di layout non ha dovuto combattere tanto per aggiornare tutte le risorse.

Volevo solo condividere qualcosa che ha fatto un miracolo per noi che potevi provare.

0

Questa è una ipotesi semi-selvaggia, ma mi chiedo se sarebbe utile impostare Visibilità su Collaps su schede che non sono selezionate. (Presumo virtualizzazione fila è abilitata sul DataGrid. Questo mi ha aiutato molto in passato.)

mia ipotesi semibrado si basa principalmente su questo tip e sulla mia comprensione intermedio l'informazione contenuta here.

+1

In realtà ho riscritto l'esempio fornito con MVVM e mostrato il contenuto attivo in un ContentControl che utilizzava un convertitore per renderizzare le viste con un solo attivo ed era ancora lento – Bryant

+0

@Bryant è esattamente il mio problema. per semplificarlo il più possibile.La possibile soluzione che posso vedere è creare un ContentContr personalizzato ol (probabilmente basato su ItemsControl) che, oltre all'elemento attivo, mantiene in qualche modo le altre viste in modo che non vengano rimosse dall'albero visivo e quindi non è necessario ricrearle nuovamente quando viene attivata la rispettiva vista. – gius

0

ho avuto questo problema con c1DataGrid, ho scoperto che dopo aver temi off, le schede che cambiano era veloce, e fare altre operazioni di interfaccia utente erano istantanea.

Prova anche:

  1. assicurarsi che nessuno del vostro codice viene chiamato facendo un passo attraverso con VS.
  2. Rimuovere tutti gli stili applicati
  3. se ancora lento eliminare componente per componente, forse la sua non solo la griglia di dati
  4. sostituire il vostro datagrid con c1datagrid