c# - WPF Toolkit DataGrid scrolling problemas de rendimiento-¿por qué?
performance (6)
¿En qué contenedor vive su cuadrícula de datos? Por ejemplo, si lo coloca en un visualizador de desplazamiento, la cuadrícula de datos crecerá para mostrar cada fila, lo que deshabilitará la virtualización de manera efectiva (y el scrollviewer lo hará parecer normal mientras esto sucede). Asegúrese de que el tamaño de la cuadrícula de datos esté limitado.
Realmente suena como una cosa de virtalización, si este consejo no funciona ejecuta tu aplicación a través de un generador de perfiles para asegurarte de que la virtualización está sucediendo.
Editar: Aquí hay un ejemplo de cómo usar snoop (o mole supongo) para ver rápidamente si la virtualización está funcionando. http://blogs.msdn.com/jgoldb/archive/2008/03/25/quick-tips-to-improve-wpf-app-memory-footprint.aspx
Tengo un problema de rendimiento con el (WPF Toolkit) DataGrid. Contiene alrededor de 1.000 filas (solo ocho columnas) y el desplazamiento es terriblemente lento y lento. Además, la carga inicial de la ventana que contiene el DataGrid tarda de 5 a 10 segundos.
Hice algunas investigaciones (usando Google y StackOverflow) pero no pude encontrar nada más que los consejos para activar la virtualización de la interfaz de usuario. Pero incluso después de permitir explícitamente que el desplazamiento continúe siendo muy lento.
My DataGrid está vinculado a un ICollectionView / CollectionViewSource. Se define en XAML de esta manera (las columnas se definen explícitamente, no se generan automáticamente):
<tk:DataGrid x:Name="dataGrid"
ItemsSource="{Binding Path=Bookings}"
AutoGenerateColumns="False"
Grid.Row="1"
EnableRowVirtualization="True"
EnableColumnVirtualization="True"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling">
...
</tk:DataGrid>
El DataContext para toda la ventana está configurado para una instancia de la clase que contiene el ICollectionView al que está vinculado DataGrid.
Cada publicación de blog o foro que encontré elogiaba el rendimiento de DataGrid, así que evidentemente estoy haciendo algo muy mal. Como soy bastante nuevo en WPF en general y especialmente en DataGrid, no tengo ni idea de cómo mejorar esto. ¿Alguien tiene algún consejo para mí? ¿Cuál es su experiencia con DataGrid? ¿Qué estoy haciendo mal?
Editar: solo siguió los consejos de esta pregunta para establecer el ancho de todas las columnas en "Auto". Eso no cambió el mal rendimiento de desplazamiento. Además, no estoy utilizando DataGridTemplateColumns (solo algunas DataGridTextColumns y dos DataGridComboBoxColumns).
Edit2: utilicé Snoop para ver mi aplicación. Lo que veo sugiere que la virtualización está funcionando (solo 19 filas, no mil). Pero cada fila contiene 52 elementos, por lo que se suman a más de mil elementos. ¿Podría ser ese el problema?
¡Muchas gracias!
Después de finalmente hacer el tiempo para construir mi aplicación contra una versión actualizada de WPF, el problema de desplazamiento parece haber desaparecido por completo. Entonces, si alguien todavía usa la versión del Toolkit de DataGrid, simplemente "actualice" la versión incluida en el marco y debería estar bien.
El DataGrid tiene una propiedad Attached, ScrollViewer.CanContentScroll , que maneja este comportamiento. Para obtener un desplazamiento suave, deberá configurarlo en False .
En lo que respecta a la carga inicial, me pareció necesario ampliar la API pública para mejorar drásticamente un gran número de cargas de columna: estamos hablando de minutos a menos de un segundo. Dicho esto, tengo problemas similares con el rendimiento de desplazamiento, incluso más de 500 columnas es muy lento para desplazarse.
Configuración de columnas dentro de mi grilla de datos derivada:
var columns = new DataGridColumnCollection(true, dataGrid);
for (int i = 0; i < pivotTable.DetailsColumnCount; i++)
{
if (!pivotTable.NullColumns.Contains(i))
{
columns.Add(new PivotDetailColumn(pivotTable, i));
}
}
columns.ForceUpdate();
dataGrid.Columns = columns;
dataGrid.ItemsSource =
Enumerable.Range(0, pivotTable.DetailsRowCount)
.Where(i => !pivotTable.NullRows.Contains(i)) // Only non null rows
.ToList();
Correcciones a DataGridColumnCollection:
public class DataGridColumnCollection : ObservableCollection<DataGridColumn>
{
private bool _DeferColumnChangeUpdates = false;
public DataGridColumnCollection(bool deferColumnChangeUpdates, DataGrid dataGridOwner)
: this(dataGridOwner)
{
_DeferColumnChangeUpdates = deferColumnChangeUpdates;
}
public DataGridColumnCollection(DataGrid dataGridOwner)
{
Debug.Assert(dataGridOwner != null, "We should have a valid DataGrid");
DisplayIndexMap = new List<int>(5);
_dataGridOwner = dataGridOwner;
RealizedColumnsBlockListForNonVirtualizedRows = null;
RealizedColumnsDisplayIndexBlockListForNonVirtualizedRows = null;
RebuildRealizedColumnsBlockListForNonVirtualizedRows = true;
RealizedColumnsBlockListForVirtualizedRows = null;
RealizedColumnsDisplayIndexBlockListForVirtualizedRows = null;
RebuildRealizedColumnsBlockListForVirtualizedRows = true;
}
#region Protected Overrides
public void ForceUpdate()
{
if (DisplayIndexMapInitialized)
{
UpdateDisplayIndexForNewColumns(this, 0);
}
InvalidateHasVisibleStarColumns();
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
if (!_DeferColumnChangeUpdates)
{
if (DisplayIndexMapInitialized)
{
UpdateDisplayIndexForNewColumns(e.NewItems, e.NewStartingIndex);
}
InvalidateHasVisibleStarColumns();
}
break;
Estoy usando .NET 4.0 y sigo teniendo problemas de rendimiento de desplazamiento. Lo que hice fue - virtualización deshabilitada. Establecí EnableRowVirtualization en ''falso'' en DataGrid. Esto mejoró considerablemente el rendimiento de desplazamiento.
Sugeriría que no asuma que lo que ofrece WPF es útil en todas las situaciones.
Podría intentar agregar los elementos uno a uno (o fila por fila) en la cuadrícula de datos y actualizar el hilo de la interfaz de usuario después de cada adición. De esta forma, el usuario ve que se realiza la carga y no parece que la aplicación no esté haciendo nada. Vea aquí una descripción más detallada de este método