2008-09-15 25 views
7

En mi aplicación tengo un control DataGridView que muestra datos para el objeto seleccionado. Cuando selecciono un objeto diferente (en un cuadro combinado de arriba), necesito actualizar la grilla. Lamentablemente, los diferentes objetos tienen datos completamente diferentes, incluso columnas diferentes, por lo que necesito borrar todos los datos y columnas existentes, crear nuevas columnas y agregar todas las filas. Cuando se hace esto, todo el control parpadea horriblemente y lleva siglos. ¿Existe una forma genérica de obtener el control en estado de actualización para que no se vuelva a pintar y luego volver a pintar después de que termine todas las actualizaciones?Parpadeo durante las actualizaciones de los controles en WinForms (por ejemplo, DataGridView)

Es ciertamente posible con TreeViews:

myTreeView.BeginUpdate(); 
try 
{ 
    //do the updates 
} 
finally 
{ 
    myTreeView.EndUpdate(); 
} 

¿Hay una manera genérica para hacer esto con otros controles, DataGridView en particular?

ACTUALIZACIÓN: Lo siento, no estoy seguro de que fuera lo suficientemente claro. Veo el "parpadeo", porque después de una sola edición del control se volvió a pintar en la pantalla, para que pueda ver la barra de desplazamiento de contracción, etc.

+0

agregue esto en su DataGridView DoubleBuffered (verdadero); –

Respuesta

7

En lugar de añadir las filas de la cuadrícula de datos uno a la vez, utilice el método DataGridView.Rows.AddRange añadir todas las filas a la vez . Eso solo debería actualizar la pantalla una vez. También hay un DataGridView.Columns.AddRange para hacer lo mismo con las columnas.

+0

Saludos, esto parece lo mejor que se puede obtener con DataGridView – Grzenio

1

suena como usted quiere búfer doble:

http://www.codeproject.com/KB/graphics/DoubleBuffering.aspx

Aunque esto se usa principalmente para controles individuales, puede implementar esto en su formulario o control de Windows Forms.

+2

Intenté doble buffering, pero no ayudó mucho. Creo que el problema es que intenta volver a pintar después de cada fila que agrego, por lo que termina actualizando las primeras filas varias veces. – Grzenio

1

Desafortunadamente, creo que Thins podría ser simplemente un subproducto del .NET Framework. Estoy experimentando un parpadeo similar aunque con controles personalizados. Muchos de los materiales de referencia que he leído indican esto, junto con el hecho de que el método del doble buffer no eliminó ningún parpadeo.

6

Doblebuffering no ayudará aquí, ya que sólo de tampones dobles pintan las operaciones, el parpadeo de la OP está viendo es el resultado de múltiples operaciones de pintura:

  • Contenidos de control Clear -> volver a pintar
  • claro columnas -> volver a pintar
  • pueblan nuevas columnas -> volver a pintar
  • añadir filas -> volver a pintar

entonces hay cuatro repintados para actualizar el control, de ahí el parpadeo. Desafortunadamente, no todos los controles estándar tienen el BeginUpdate/EndUpdate que eliminaría todas las llamadas a repintar hasta que se llame a EndUpdate. Esto es lo que puede hacer:

  1. tener un control diferente para cada conjunto de datos y Mostrar/Ocultar los controles,
  2. Retire el control de su matriz, actualizar y luego agregar el control de nuevo,
  3. Escriba su propio control.

Las opciones 1 y 2 seguirían parpadeando un poco.

En el programa .NET GUI en el que estoy trabajando, creé un conjunto de controles personalizados que eliminaban todo el parpadeo.

+0

Sí, estoy bastante seguro de que este es exactamente el problema. Y como tengo que agregar> 50 filas, puedes ver cómo está creciendo la grilla. Cuando creó los controles, ¿extendió la vista de cuadrícula de datos existente o escribió uno nuevo desde cero? – Grzenio

+0

Los escribí desde cero, derivados de UserControl y todos son muy específicos de la aplicación. – Skizz

8

El control .NET admite los métodos SuspendLayout y ResumeLayout. Elija el control principal apropiado (es decirel control que aloja los controles que desea rellenar) y hacer algo como lo siguiente:

this.SuspendLayout(); 

// Do something interesting. 

this.ResumeLayout(); 
+2

Sí, lo intenté pero simplemente no funciona :( – Grzenio

2

Esto funcionó para mí.

http://www.syncfusion.com/faq/windowsforms/search/558.aspx

Básicamente se trata de derivados de control deseado y el establecimiento de los siguientes estilos.

SetStyle(ControlStyles.UserPaint, true); 
SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
SetStyle(ControlStyles.DoubleBuffer, true); 
7

La gente parece olvidar una solución simple para esto:

Object.Visible = false; 

//do update work 

Object.Visible = true; 

Sé que parece raro, pero que funciona. Cuando el objeto no es visible, no se volverá a dibujar. Aún así, sin embargo, necesita hacer la actualización begin y end.

+0

Esto debería tener muchos más puntos, me habría ahorrado mucho tiempo. Otras sugerencias no lo hicieron trabajo para mi caso de uso, pero esto fue perfecto. ¡Gracias! –

0

También puede probar esto, su trabajo.

public static void DoubleBuffered(Control formControl, bool setting) 
{ 
    Type conType = formControl.GetType(); 
    PropertyInfo pi = conType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); 
    pi.SetValue(formControl, setting, null); 
} 
Cuestiones relacionadas