WPF DataGrid es muy lento para procesar
performance render (8)
¿Tienes?
- ¿Habilitado
VirtualizingStackPanel.VirtualizationMode
para una cuadrícula? Si no, trata de establecer. - Establecer VirtualizingStackPanel.IsVirtualizing = "true" para DataGrid
- Envuelto una rejilla por un contenedor StackPanel? Si es así, trate de eliminar.
- ¿Envuelto un Grid por un control ScrollViewer externo? Si es así, trate de eliminar.
Un punto más, ¿podría enlazar toda la colección de artículos a la vez en lugar de agregar cada elemento a la cuadrícula?
He intentado usar tanto un DataGrid personalizado como el stock en WPF. He intentado rellenarlos manualmente, así como a través de enlaces. En ambos casos son lentos.
Tengo un scenerio donde el usuario hace clic en un botón y aparece un DataGrid con los datos apropiados. Actualmente estoy en modo de prueba de concepto y solo estoy usando datos de muestra. Tengo un DataSet con una tabla que tiene 10 filas en él.
Si no adjunto ningún dato al DataGrid cuando hago clic en el botón, el DataGrid vacío se muestra casi al instante, un usuario no puede percibir un retraso. Tan pronto como agrego 10 filas de datos, para 6 columnas, el retraso es de aproximadamente 2 segundos, muy notable para el usuario.
Incluso intenté rellenar con datos vacíos, solo para que aparezca una cuadrícula vacía y es igual de lento.
for (int i = 0; i < 10; i++)
_dataGrid.Items.Add("");
Pongo un temporizador para contar las marcas de tiempo cuando se hace clic en el botón para cuando se ejecuta todo el código para dibujar el DataGrid y es de alrededor de 20 milisegundos, por lo que el código se ejecuta muy rápido, pero en la pantalla es donde está el gran retraso. . Probé un GridView y se muestra mucho más rápido en la pantalla.
He escuchado varios informes de dibujos lentos de DataGrid con escenarios complejos y utilizando miles de filas, pero esto es tan simple como lo hace, 6 columnas por 10 filas llenas de datos vacíos.
Para la visualización de solo lectura, ¿es GridView una opción igualmente viable para el DataGrid?
Actualizar
Aquí está la creación de mis columnas.
DataGridTextColumn column = new DataGridTextColumn();
column.ColumnWidthChanged += new ColumnWidthChangedEventHandler(column_ColumnWidthChanged);
column.Header = entity.GetPropertyValue("ColumnLabel");
column.Binding = new Binding(entity.GetPropertyValue("Tag"));
column.Width = new DataGridLength(entity.GetPropertyDouble("DisplaySize"));
_dataGrid.Columns.Add(column);
Así es como vinculo el conjunto de datos con 10 filas en él.
_dataGrid.ItemsSource = ds.Tables[0].DefaultView;
_dataGrid.DataContext = ds.Tables[0];
No estoy seguro de lo que puedo hacer de manera diferente.
Bueno, agregando un poco más (sé que es un tema muy antiguo, pero aún así ayuda a alguien) ...
Lo intenté
EnableColumnVirtualization="True" VirtualizingPanel.VirtualizationMode="Recycling"
EnableRowVirtualization="True"
para el enlace de DataGrid ( AutoGenerateColumns="True"
) a DataTable.DefaultView () y Sin efecto en la velocidad, todavía era horrible para Speed, así como para la navegación entre filas. Entonces, se me ocurrió una solución para establecer la altura fija y el ancho de DataGrid. Además también me puse
RowHeight="23"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
Esto hace que mi página se llene muy rápido ... En lugar de 2 minutos, ahora toma apenas 10-12 segundos.
Espero que ayude a alguien.
Nota: estoy usando .Net 4.5
En mi caso, tuve un problema con DataGridCell ControlTemplate que ralentizó la representación.
Tenga en cuenta que las velocidades de carga relativas para grandes conjuntos de datos son muy diferentes para usar TextBlock (que no es texto seleccionable) o TextBox en modo ReadOnly:
Tiempo de carga 59 segundos:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellTextStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<TextBox IsReadOnly="True" Text="{Binding Mode=OneWay}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Tiempo de carga 21 segundos:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellTextStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<ContentPresenter Content="{Binding}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Tiempo de carga 16 segundos:
<Style TargetType="{x:Type DataGridCell}" x:Key="DataGridCellTextStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<TextBlock Text="{Binding}"></TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Para mi fue:
<Setter Property=''ScrollViewer.CanContentScroll'' Value=''False'' />
Quité esto del estilo y la representación se hizo rápida.
Tengo el mismo problema con la cuadrícula de datos enlazados, y me doy cuenta de que en la primera carga es rápido pero en segundo lugar y luego es lento. Así que cuando agrego en código
DataGrid.ItemsSource = Nothing
y luego TableAdapter.Fill(Mydataset.MyStoredProcedure,....) DataGrid.ItemsSource=Mydataset.MyStoredProcedure
se volvió muy RÁPIDO
Tengo un Surface Pro 3 en el que mi red de datos, con alrededor de 200 filas y 10 columnas, fue muy lenta en el desplazamiento, desigual y vacilante.
Pensé que era la red, pero en realidad era que la tarjeta gráfica no podía mantenerse al día, esperar por ella, un efecto de sombra en la propia cuadrícula de datos, aunque el fondo del control estaba configurado en un color sólido.
Comenté el efecto y fue 4-5 veces más rápido.
Espero que esto ayude.
Una sugerencia general para los problemas de rendimiento de DataGrid
: tuve un problema con el DataGrid en el que tomó literalmente unos segundos para actualizar después de cambiar el tamaño de la ventana, ordenar las columnas, etc. y cerré la interfaz de usuario de la ventana mientras lo hacía (1000 filas, 5 columnas ).
Se trató de un problema (¿error?) Con los cálculos de tamaño de WPF. Lo tenía en una cuadrícula con RowDefinition
Height="Auto"
que provocaba que el sistema de renderización intentara volver a calcular el tamaño del DataGrid en tiempo de ejecución al medir el tamaño de cada columna y fila, probablemente al llenar toda la cuadrícula ( como yo lo entiendo). Se supone que debe manejar esto inteligentemente de alguna manera, pero en este caso no lo fue.
Una comprobación rápida para ver si se trata de un problema relacionado es establecer las propiedades de alto y Width
de la cuadrícula de datos en un tamaño fijo durante la prueba e intentar ejecutar de nuevo. Si se restaura su rendimiento, una solución permanente puede estar entre estas opciones:
- Cambie los tamaños de los elementos que contienen para que sean relativos (*) o valores fijos
- Establezca
MaxHeight
yMaxWidth
de DataGrid en un valor fijo mayor al que podría obtener en uso normal - Pruebe otro tipo de contenedor con una estrategia de cambio de tamaño diferente (
Grid
,DockPanel
, etc.)
Un blog que encontré en Google me dio una especie de solución. Como dijo el autor, deshabilité GroupStyle y se resolvió el problema de la velocidad de representación. Pero necesitaba agrupar. El autor dijo
VirtualizingPanel.IsVirtualizingWhenGrouping
Se agrega a .NET 4.5. Así que lo puse a verdad. Ahora el renderizado es rápido con la agrupación. El problema es ... el desplazamiento es desigual. No inaceptablemente desigual, pero notablemente desigual. Tuve un problema similar cuando intenté crear un TreeView con más de 2000 nodos expandidos. Sin la virtualización, la representación fue lenta pero el desplazamiento fue suave. Con la virtualización, el renderizado fue rápido pero el desplazamiento fue desigual.
¿Por qué no podemos tener ambos ...