2009-03-30 25 views
31

Estoy trabajando con la cuadrícula de datos de WPF Toolkit y está desplazándose extremadamente lento en este momento. La grilla tiene 84 columnas y 805 filas. (Incluye 3 columnas fijas y el encabezado está fijo.) El desplazamiento horizontal y vertical es extremadamente lento. La virtualización está activada y he habilitado la virtualización de columnas y la virtualización de filas explícitamente en el xaml. ¿Hay algo de qué preocuparse que realmente pueda afectar el rendimiento, como los métodos de enlace, o qué xaml hay en cada plantilla de celda?WPF Datagrid Performance

Una cosa a tener en cuenta es que estoy agregando dinámicamente las columnas en la creación de la cuadrícula de datos. ¿Podría estar afectando algo? (También creo dinámicamente el celltemplate al mismo tiempo para que mis enlaces se configuren correctamente.)

A continuación se muestra el código de la plantilla para la mayoría de las celdas que se generan. Básicamente para las columnas que necesito agregar dinámicamente (que es la mayoría de ellas), recorro mi lista y agrego las columnas usando el método AddColumn, además construyo dinámicamente la plantilla para que las declaraciones vinculantes indexen correctamente el elemento correcto en la colección para esa columna. La plantilla no es demasiado compleja, solo dos TextBlocks, pero yo vinculo cuatro propiedades diferentes en cada uno. Parece que yo era capaz de exprimir un poco más de rendimiento por los cambios de las fijaciones para 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 es aproximadamente 100 veces más rápido que incluso los controles de cuadrícula de datos WPF comerciales más rápidos. Datagrids realmente resalta las debilidades de WPF. – Damien

+3

La cuadrícula de datos Delphi de 15 años funciona más rápido en un hardware de 15 años. – KornMuffin

Respuesta

20

Ya que no puede ver su código fuente es bastante difícil para ayudarle. Especialmente porque el rendimiento de una aplicación WPF está influenciado por muchas cosas. Para algunos consejos sobre qué buscar, ver Optimizing WPF Application Performance. Y sí, importa mucho qué xaml se use en cada celda. Porque generalmente los problemas de rendimiento se reducen a "demasiados elementos". ¿Sabías que un TextBox creo que son 30 elementos individuales? Le recomiendo que use el Performance Profiling Tools for WPF para obtener más información sobre su problema específico. Intente minimizar la cantidad de elementos que está utilizando (por ejemplo, cambiando de TextBox a TextBlock cuando corresponda).

También debe comprobar si existen problemas de rendimiento en cualquier PC en la que pruebe la aplicación. Tal vez la PC que está usando está forzando a WPF a un renderizado basado en software. ¿O está utilizando algún BitmapEffects?

Editar:
En cuanto a su código que le sugeriría cambiar

column.Width = DataGridLength.Auto;

a un ancho fijo razonable, ya que la cuadrícula de datos no tiene que volver a calcular el ancho cambia dinámicamente cada vez que algo (como la adición filas, o incluso desplazamiento).

+6

Usando el .NET 4.0 DataGrid (antiguo toolkit uno), tengo el mismo maldito problema, y ​​solo estoy usando DataGridTextBoxColumns. Tengo menos filas (20, lo que significa que la virtualización de filas es inútil en mi caso), pero 100 cols (aquí la virtualización hace una gran diferencia, pero todavía demora alrededor de 2 segundos para mostrar la cuadrícula y 1 segundo para actualizar cada vez que se desplaza horizontalmente ... .). Establecer el bindingMode en oneWay no hizo ninguna diferencia para mí :(. Todavía estoy tratando de encontrar una manera de hacer las cosas más rápido, pero por lo que pude deducir, es toda la DG que simplemente está creando las células muy lentamente ... . – David

1

¿Tiene alguna posibilidad de tener una tableta de cualquier tipo instalada (a través de USB o una Tablet PC)?

Encontré un error de rendimiento en la cuadrícula de datos de WPF cuando uso una tableta. He publicado un video y se reconoce por MS here in this thread

Cheers, Jon

+2

Desafortunadamente, DataGrid de WPF es bastante lento sin ningún tipo de error relacionado con la tableta. – EFraim

+0

Lo uso en una aplicación de misión crítica en tiempo real (probablemente unas 20-30 instancias de él, con 2K-3K registros por cuadrícula) y es rápido para –

+0

Bueno, el problema es que hay un montón de WinForms/soluciones nativas que manejan 100K filas/20 columnas sin problemas. No tuve tanta suerte con DataGrid. – EFraim

10

Un consejo general para los problemas de rendimiento de DataGrid: tuve un problema con la cuadrícula de datos en la que tomó literalmente segundos para refrescarse después de un cambio de tamaño de ventana , clasificación de columnas, etc. y bloqueado la interfaz de usuario de la ventana mientras lo estaba haciendo (1000 filas, 5 columnas).

Todo se redujo a un problema (¿error?) Con los cálculos de tamaño de WPF. Lo tenía en una grilla con RowDefinition Height = "Auto", lo que causaba que el sistema de renderizado intentara recalcular el tamaño de DataGrid en tiempo de ejecución midiendo el tamaño de cada columna y fila, presumiblemente al llenar toda la grilla (como yo lo entiendo).Se supone que debe manejar esto inteligentemente de alguna manera, pero en este caso no fue así.

Una comprobación rápida para ver si este es un problema relacionado es establecer las propiedades de altura y ancho de DataGrid en un tamaño fijo durante la prueba e intentar ejecutarlo nuevamente. Si el rendimiento es restaurada, una solución permanente puede ser una de estas opciones:

  • Cambiar el tamaño de los elementos que contienen a ser relativo (*) o valores fijos
  • Conjunto MaxHeight y MaxWidth de la cuadrícula de datos a una valor fijo más grande de lo que podría ponerse en uso normal
  • Pruebe con otro tipo de recipiente con diferente estrategia de cambio de tamaño (Grid, DockPanel, etc)
+1

Configuración en DataGrid.Height a un valor fijo resuelto el problema en mi caso. ¡Gracias! – nightcoder

+1

Configuración de DataGrid.MaxHeight también ayuda s. – nightcoder

1

tuve un caso en el que mi objeto subyacente tenía una propiedad con sólo el colocador. Se puede acceder a la misma propiedad implementando ITypedList en la colección y a través de TypeDescriptionProvider/ICustomTypeDescriptor en los objetos individuales. Eliminar la propiedad o agregar un getter resolvió los problemas de rendimiento.

1

Una cosa que sugeriría en tales escenarios es ver cómo ha aplicado el estilo y qué estilo tiene cada celda. El estilo aplicado si tiene un árbol visual complejo tiende a degradar el rendimiento.

También puede probar la opción de desplazamiento diferido en la última cuadrícula de datos de WPF.

2

en uno de mis proyectos la configuración siguiente estilo rejilla estaba causando un problema mayor rendimiento:

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

Cuando quité el ajuste ScrollViewer.CanContentScroll, el problema de rendimiento se había ido.