2009-10-27 19 views
8

estoy pintando mis filas de un DataGridView como esto:C color de fondo # WinForms DataGridView haciendo demasiado lento

private void AdjustColors() 
    {    
     foreach (DataGridViewRow row in aufgabenDataGridView.Rows) 
     { 
      AufgabeStatus status = (AufgabeStatus)Enum.Parse(typeof(AufgabeStatus), (string)row.Cells["StatusColumn"].Value); 

      switch (status) 
      { 
       case (AufgabeStatus.NotStarted): 
        row.DefaultCellStyle.BackColor = Color.LightCyan; 
        break; 
       case (AufgabeStatus.InProgress): 
        row.DefaultCellStyle.BackColor = Color.LemonChiffon; 
        break; 
       case (AufgabeStatus.Completed): 
        row.DefaultCellStyle.BackColor = Color.PaleGreen; 
        break; 
       case (AufgabeStatus.Deferred): 
        row.DefaultCellStyle.BackColor = Color.LightPink; 
        break; 
       default: 
        row.DefaultCellStyle.BackColor = Color.White; 
        break; 
      } 
     }   
    } 

Entonces me llaman en el método OnLoad:

protected override void OnLoad(EventArgs e) 
     { 
      base.OnLoad(e); 

      AdjustColors();   
     } 

prefiero OnLoad a OnPaint o algo así porque OnPaint se llama con mucha frecuencia.

La pregunta: ¿Por qué tarda aproximadamente 100 - 200 ms para cambiar el fondo de cada fila? Temprano, estaba doint CellPaint .. pero tuve problemas al desplazarme con refrescante ..

+0

Te refieres toma 100 - 200ms por fila? Eso suena bastante pesado. – leppie

+0

¿Cuántas filas? ¿Tiene doble buffer en el formulario? ¿Has intentado utilizar el evento CellFormatting? – stuartd

Respuesta

10

En lugar de cambiar el color de todo DataGrid a la vez, debe dejar que administre la representación anulando el evento CellFormatting. Las filas solo se pintarán cuando realmente se muestren en la pantalla.

private void aufgabenDataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
{ 
    DataGridViewRow row = aufgabenDataGridView.Rows[e.RowIndex]; 
    AufgabeStatus status = (AufgabeStatus) Enum.Parse(typeof(AufgabeStatus), (string) row.Cells["StatusColumn"].Value); 

    switch (status) 
    { 
    case (AufgabeStatus.NotStarted): 
     e.CellStyle.BackColor = Color.LightCyan; 
     break; 
    case (AufgabeStatus.InProgress): 
     e.CellStyle.BackColor = Color.LemonChiffon; 
     break; 
    case (AufgabeStatus.Completed): 
     e.CellStyle.BackColor = Color.PaleGreen; 
     break; 
    case (AufgabeStatus.Deferred): 
     e.CellStyle.BackColor = Color.LightPink; 
     break; 
    default: 
     e.CellStyle.BackColor = Color.White; 
     break; 
    } 

} 

Si esto sigue siendo demasiado lento, trate de conseguir el objeto real de la fila está obligado a:

... 
DataGridViewRow row = aufgabenDataGridView.Rows[e.RowIndex]; 
var aufgabe = (Aufgabe) row.DataBoundItem; 
AufgabeStatus status = aufgabe.Status; 
... 
+0

Bueno, esta solución funciona a la perfección. –

+0

Eso podría ser una prueba de que no puedo manejar la pintura yo mismo, pero debo confiar en el mecanismo proporcionado por MS. ¡Ahora se recolorean todas las filas inmediatamente! –

+0

Y eliminé ese Enum.Análisis según lo propuesto por ShDevMan –

2

Probablemente sea la llamada Enum.Parse, tiene un rendimiento pobre. Debería intentar cambiarlo a una búsqueda del diccionario para ver si eso mejora el rendimiento. Consulte esto post

+0

Tienes razón, que Enum.Parse es lo suficientemente lento. Prefiero acceder al DataBoundItem directamente. –

2

Como dijo SwDevMan1, primero debe trabajar para eliminar la llamada Enum.Parse. ¿Estás usando el enlace de datos para poblar la grilla? De ser así, puede usar Filas [índice] .DataBoundItem para acceder al objeto vinculado a datos para la fila y acceder directamente al estado AufgabeStatus.

El segundo truco que sugeriría es llamar a SuspendLayout() y ResumeLayout() antes y después, respectivamente, manipulando la grilla.

+0

Quité la llamada de Parse. Sí, estoy usando DataBounding. Accedí al elemento directamente a través de DataBoundItem. Intenté Suspender y reanudar. Es más rápido ... pero 15 filas todavía están coloreadas en unos 400 ms. –

2

También es una buena idea solamente establecer las propiedades si difieren del valor esperado. De esta forma no desencadenarás una sobrecarga interna de DataGridView no deseada.

Si todas las celdas de una fila están formateadas de la misma manera, puede hacer el formateo en el nivel de fila en lugar del nivel de celda.

DataGridViewCellStyle rowStyle = row.DefaultCellStyle; 
if (rowStyle.BackColor != status.BackColor) { 
    rowStyle.BackColor = status.BackColor; 
} 
0

no trate formato de fila como row.defaultcellstyle

tratar célula individual formato en ufgabenDataGridView_CellFormatting

celular [0] = .style.backcolor color.yellow

Cuestiones relacionadas