2009-03-30 26 views
31

Sto lavorando con la griglia di dati WPF Toolkit e lo scorrimento è estremamente lento al momento. La griglia ha 84 colonne e 805 righe. (Comprese 3 colonne fisse e l'intestazione è fissa.) Lo scorrimento sia in orizzontale che in verticale è estremamente lento. La virtualizzazione è attiva e ho abilitato la virtualizzazione delle colonne e la virtualizzazione delle righe esplicitamente in xaml. C'è qualcosa a cui prestare attenzione che può davvero influire sulle prestazioni, come i metodi di associazione, o che cosa è xaml in ogni esempio di cellula?Prestazioni Datagrid WPF

Una cosa da notare è che sto aggiungendo dinamicamente le colonne alla creazione del datagrid. Potrebbe avere effetto su qualcosa? (Creo anche dinamicamente il modello di cella allo stesso tempo in modo che i miei binding siano impostati correttamente.)

Di seguito è riportato il codice del modello per la maggior parte delle celle generate. Fondamentalmente per le colonne che ho bisogno di aggiungere dinamicamente (che è la maggior parte di esse), faccio scorrere il mio elenco e aggiungo le colonne usando il metodo AddColumn, inoltre creo dinamicamente il modello in modo che le istruzioni di binding indicizzino correttamente l'elemento giusto nella raccolta per quella colonna. Il modello non è troppo complesso, solo due TextBlocks, ma io lego quattro diverse proprietà su ciascuno. Sembra come se fossi in grado di spremere un po 'di più le prestazioni da cambiamenti le associazioni di OneWay:

private void AddColumn(string s, int index) 
    { 
     DataGridTemplateColumn column = new DataGridTemplateColumn(); 
     column.Header = s; 
     //Set template for inner cell's two rectangles 
     column.CellTemplate = CreateFactViewModelTemplate(index); 
     //Set Style for header, ie rotate 90 degrees 
     column.HeaderStyle = (Style)dgMatrix.Resources["HeaderRotateStyle"]; 
     column.Width = DataGridLength.Auto; 
     dgMatrix.Columns.Add(column); 
    } 


    //this method builds the template for each column in order to properly bind the rectangles to their color 
    private static DataTemplate CreateFactViewModelTemplate(int index) 
    { 
     string xamlTemplateFormat = 
      @"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" 
      xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""> 
      <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition /> 
       <ColumnDefinition /> 
      </Grid.ColumnDefinitions> 
      <TextBlock Grid.Column=""0"" MinHeight=""10"" MinWidth=""10"" HorizontalAlignment=""Stretch"" Padding=""3 1 3 1"" TextAlignment=""Center"" Foreground=""{Binding Path=FactViewModels[~Index~].LeftForeColor,Mode=OneWay}"" Background=""{Binding Path=FactViewModels[~Index~].LeftColor,Mode=OneWay}"" Text=""{Binding Path=FactViewModels[~Index~].LeftScore,Mode=OneWay}"" /> 
      <TextBlock Grid.Column=""1"" MinHeight=""10"" MinWidth=""10"" HorizontalAlignment=""Stretch"" Padding=""3 1 3 1"" TextAlignment=""Center"" Foreground=""{Binding Path=FactViewModels[~Index~].RightForeColor,Mode=OneWay}"" Background=""{Binding Path=FactViewModels[~Index~].RightColor,Mode=OneWay}"" Text=""{Binding Path=FactViewModels[~Index~].RightScore,Mode=OneWay}"" /> 
      </Grid> 
      </DataTemplate>"; 




     string xamlTemplate = xamlTemplateFormat.Replace("~Index~", index.ToString()); 

     return (DataTemplate)XamlReader.Parse(xamlTemplate); 
    } 
+11

Sì, Microsoft Excel è circa 100 volte più veloce persino dei più veloci controlli di datagrid commerciali WPF. Datagrids evidenzia davvero i punti deboli di WPF. – Damien

+3

Il datagrid di Delphi vecchio di 15 anni viene eseguito più rapidamente su hardware vecchio di 15 anni. – KornMuffin

risposta

20

Dal momento che non riesco a vedere il codice sorgente è abbastanza difficile per aiutarvi. Soprattutto perché le prestazioni di un'applicazione WPF sono influenzate da molte cose. Per alcuni suggerimenti su cosa guardare fuori vedi Optimizing WPF Application Performance. E sì - importa molto che xaml è usato in ogni cella. Perché in genere i problemi di prestazioni si riducono a "troppi elementi". Lo sapevi che un TextBox sono 30 elementi individuali? Vi consiglio di usare lo Performance Profiling Tools for WPF per saperne di più sul vostro problema specifico. Cerca di ridurre al minimo la quantità di elementi che stai utilizzando (ad esempio passando da TextBox a TextBlock, dove appropriato).

Inoltre, è necessario verificare se i problemi di prestazioni esistono su qualsiasi PC su cui si prova l'applicazione. Forse il PC che stai usando sta forzando WPF nel rendering basato su software. O stai usando BitmapEffects?

Edit:
Guardando il codice vorrei suggerire di cambiare

column.Width = DataGridLength.Auto;

ad una larghezza fissa ragionevole, dal momento che il datagrid non deve ricalcolare la larghezza dinamicamente ogni volta che qualcosa cambia (come l'aggiunta di righe, o anche a scorrimento).

+6

Utilizzo di .net 4.0 DataGrid (ex toolkit uno), ho lo stesso dannato problema e sto usando solo DataGridTextBoxColumns. Ho meno righe (20, il che significa che la virtualizzazione delle righe è inutile nel mio caso), ma 100 cols (qui la virtualizzazione fa una grande differenza, ma ci vogliono ancora circa 2 secondi per mostrare la griglia e 1sec per aggiornare ogni volta che scorri in orizzontale .. .). L'impostazione di bindingMode su oneWay non ha fatto alcuna differenza per me :(. Sto ancora cercando di capire un modo per rendere le cose più veloci, ma da quello che potrei raccogliere, è l'intero DG che è semplicemente molto lento a creare le celle .. – David

1

Avete per caso installato un tablet di qualsiasi tipo (tramite USB o tablet PC)?

Ho trovato un bug di prestazioni nel datagrid WPF quando si utilizza un tablet. Ho postato un video ed è riconosciuto da MS here in this thread

Cheers, Jon

+2

Sfortunatamente il DataGrid di WPF è molto lento senza alcun tipo di bug relativo al tablet – EFraim

+0

Lo uso in un'app in tempo reale mission critical (probabilmente circa 20-30 istanze di esso, con record 2K-3K per griglia) ed è veloce per –

+0

Bene, ci sono un sacco di soluzioni WinForms/native che gestiscono 100K righe/20 colonne senza intoppi.Non è così fortunato con DataGrid. – EFraim

10

Un consiglio generale per problemi di prestazioni DataGrid: ho avuto un problema con il DataGrid in cui ha preso letteralmente secondi per rinfrescarsi dopo un ridimensionamento della finestra , ordinamento di colonne, ecc. e bloccato l'interfaccia utente della finestra mentre lo faceva (1000 righe, 5 colonne).

Si è verificato un problema (bug?) Con i calcoli di dimensionamento WPF. Lo avevo in una griglia con RowDefinition Height = "Auto" che stava facendo sì che il sistema di rendering provasse a ricalcolare la dimensione di DataGrid in fase di esecuzione misurando la dimensione di ogni colonna e ogni riga, presumibilmente riempiendo l'intera griglia (come ho capito).Dovrebbe gestirlo in modo intelligente in qualche modo ma in questo caso non lo era.

Un controllo rapido per vedere se questo è un problema correlato è impostare le proprietà Altezza e Larghezza di DataGrid su una dimensione fissa per la durata del test e provare a eseguire nuovamente. Se la prestazione viene ripristinata, una correzione permanente può essere tra queste opzioni:

  • modificare le dimensioni degli elementi che contengono sia relativa (*) o valori fissi
  • Set MaxHeight e MaxWidth del DataGrid a un valore fisso più grande di quello che potrebbe entrare in uso normale
  • Provare un altro tipo di contenitore con diversa strategia di ridimensionamento (griglia, DockPanel, ecc)
+1

Impostazione su DataGrid.Altezza a un valore fisso risolto il problema nel mio caso. Grazie! – nightcoder

+1

Impostazione di DataGrid.MaxHeight anche aiuto S. – nightcoder

1

ho avuto un caso in cui il mio oggetto sottostante aveva proprietà con solo setter. La stessa proprietà era accessibile implementando ITypedList nella raccolta e tramite TypeDescriptionProvider/ICustomTypeDescriptor sui singoli oggetti. O rimuovere la proprietà o aggiungere un getter ha risolto i problemi di prestazioni.

1

Una cosa che suggerirei in tali scenari è osservare come hai applicato lo stile e quale è lo stile su ogni cella. Lo stile applicato se ha una struttura visiva complessa tende a degradare le prestazioni.

Si potrebbe anche provare l'opzione Scorrimento differito sull'ultimo Datagrid WPF.

2

in uno dei miei progetti l'impostazione seguente stile di griglia stava causando un grave problema di prestazioni:

<Style TargetType='{x:Type controls:DataGrid}'> 
    <Setter Property='ScrollViewer.CanContentScroll' Value='False' /> 
    ... 

Quando ho rimosso l'impostazione ScrollViewer.CanContentScroll, il problema di prestazioni non c'era più.