2012-03-30 14 views
23

Actualmente tenemos un DataGrid que está vinculado a un DataTable. También tiene una columna de plantilla con un CheckBox que agregamos en forma programática. Este propósito de esta columna es realizar un seguimiento de selecciones múltiples en el DataGrid.Número de visualización de virtualización de fila de DataGrid

Se utiliza una fábrica para crear el CheckBox es para cada fila.

Existen bastantes registros, por lo que la virtualización de fila se establece en verdadero para que el rendimiento sea aceptable. Sin embargo, estamos viendo un problema extraño en el que si comprobamos algunos CheckBox es en las primeras 10 filas y luego desplazamos hacia abajo unas 50 filas (la cuadrícula tiene aproximadamente 10 filas visibles al mismo tiempo), hay un montón de otras CheckBox que parece ser verificado al azar.

Si deshabilitamos la virtualización de fila, este problema no existe (pero el rendimiento es terrible). ¿Hay alguna forma de evitar esto? Alguien sabe lo que podemos estar haciendo mal?

+0

cuando dices que el rendimiento es terrible después de eliminar la virtualización, es terrible en carga o en desplazamiento. Si está en carga, hay una solución que hará que no sea terrible, en scroll es otro problema ... –

+0

Solo está en carga. Todo el rendimiento alcanzado es en el método Mostrar de la ventana que contiene DataGrid. Con la virtualización de filas, se requieren 200 ms para mostrar con 2.500 registros en DataGrid. Sin virtualización de fila, lleva 28 segundos. – WPFNewbie

+0

agregó un código para usted ... solo tuvo que ajustar el rendimiento en el trabajo hace unos días, funciona como un encanto –

Respuesta

23

Si está buscando velocidad ListView Gridview es mucho más rápido (y tiene menos funciones).

Intente desactivar el reciclaje de contenedores.

   <tk:DataGrid x:Name="dataGrid" 
      ItemsSource="{Binding Path=Bookings}" 
      AutoGenerateColumns="False" 
      EnableRowVirtualization="True" 
      EnableColumnVirtualization="True" 
      VirtualizingStackPanel.VirtualizationMode="Standard" 
      VirtualizingStackPanel.IsVirtualizing="True"> 
+3

Si escribe IsVirtualising antes de VirtualisationMode obtiene excepción (al menos está en .NET 4.5) ... usted Necesito cambiar el orden –

+0

Tuve un problema similar, excepto que el orden de las filas siguió cambiando mientras estaba desplazándome. No hice explícitamente la virtualización. Esta respuesta ayudó, sin embargo. –

+0

VirtualizationMode = "Estándar" para ganar! –

4

Si activó la virtualización debido a que el tiempo de cuadrícula de datos de carga es terrible, entonces, aquí está la solución:

  • desvío virtualización
  • asumamos/llaman unión artículos fuente de su cuadrícula de datos como " filas",

    public IEnumerable<Row> Rows {get; set;} 
    
  • añadir un alojamiento a la "fila" clase IsVisible y alternar cuando se desea cargar los datos (no cuando el hilo de interfaz de usuario decide resolver la unión y la carga de cada control)

la razón por la que esto funciona, es porque cuando se carga la red, comprueba la unión, toda la fila son invisibles, por lo que el subproceso de interfaz de usuario no tiene que pasar por todas las filas * de columnas para crearlos, puede ir a lo siguiente que necesita hacer. Por otro lado, puede detectar cuándo es el momento adecuado para convertir esas filas en visibles, cuando View.Visibility está visible, cuando ViewModel carga los datos desde algún lugar, etc. De modo que tiene el control total. A continuación, estoy iterando a través de mi fuente de artículo (filas) usando una tarea (en una cadena de fondo), sin embargo, estableciendo Visibilidad en el hilo de la interfaz de usuario.

private _isVisible = false; 

    /// <summary> 
    /// is false by default, for performance when loading first time. 
    /// </summary> 
    public bool IsVisible 
    { 
     get { return _isVisible; } 
     set 
     { 
      if (_isVisible == value) 
       return; 
      _isVisible = value; 
      RaisePropertyChanged(() => IsVisible); 
     } 
    } 
  • En la vista, cuando cuadrícula de datos es de carga no permita que a acaparar el hilo de interfaz de usuario, poniendo la iteración de filas en el subproceso de fondo, a continuación, establecer la visibilidad en true. Aunque esté en el hilo de fondo, la propiedad IsVisible cambiada lo activará para que actualice.

    private void OnGridLoaded(object sender, RoutedEventArgs e) 
    { 
        //sample bool checks, you might not need them... 
        if (firstTimeLoad && !_isDataGridLoaded) 
        { 
         Task.Factory 
          .StartNew(() => 
          { 
           /*first time loading performance tweak*/ 
           foreach (var row in _viewModel.Rows) 
            ExeOnUi(() => { row.IsVisible = true; }); 
    
           _firstTimeLoad = false; 
          }) 
        } 
    
  • se olvidó de agregar código ExeOnUi (es posible comprobar el acceso utilizando otra cosa, como whateverControl.Dispatcher.CheckAccess, sólo tiene que utilizar Microsoft.Practices.ServiceLocator):

    static void ExeOnUi (Action action) 
    { 
        var srv= ServiceLocator.Current.GetInstance<IDispatchService>(); 
        if (srv.CheckAccess()) 
         action.Invoke(); 
        else 
         srv.Invoke (action); 
    } 
    
1

acabo encuentro con un problema similar y su resuelto después de añadir UpdateSourceTrigger=PropertyChanged a la unión.

<DataGridTemplateColumn Header="Visible"> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <CheckBox IsChecked="{Binding IsShown,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 
Cuestiones relacionadas