Para reducir el parpadeo mediante el búfer doble: SetStyle frente a la anulación de CreateParam

¿Alguien puede explicar la diferencia y la relación entre

SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer, true) 

y

 protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED return cp; } } 

Se requiere que reduzcan los parpadeos, pero ¿cuándo y cómo usarlos correctamente? ¿Pueden usarse individualmente, o deben usarse en pares, y cuál es la razón para eso?

¡Gracias!

Créditos :

El primer fragmento de código fue citado de la página de MSDN ; el segundo fragmento de código se encontró en Cómo corregir el parpadeo en los controles de Usuario , el autor original es @HansPassant.

Gracias a @terrybozzlo por la explicación y @Caramiriel por la gran página que aclara el problema.

Me gustaría resumir todo lo que tengo aquí.


Por qué tenemos parpadeos

Los parpadeos generalmente ocurren cuando su formulario, o un control de contenedor, como un Panel , contiene demasiados controles (y cuando WS_CLIPCHILDREN está activado, que es el caso de forma predeterminada). Según @HansPassant:

Dibuja la imagen de fondo, dejando agujeros donde van las ventanas de control de niños. Cada control secundario recibe un mensaje para pintarse, y llenarán el agujero con el contenido de la ventana. Cuando tienes muchos controles, esos agujeros son visibles para el usuario por un tiempo. Normalmente son blancos, contrastando mal con la imagen de fondo cuando está oscuro. O pueden ser de color negro si el formulario tiene su propiedad Opacidad o TransparencyKey configurada, contrastando mal con casi cualquier cosa.

Cómo evitarlos en el Nivel de Control.

Debe establecer la propiedad DoubleBuffered del control en true . Para hacer esto, necesita derivar el control (si no es un control de usuario) del tipo básico y establecerlo en el constructor.

Por ejemplo, para obtener un Panel doble búfer, debe hacer:

 public class BufferedPanel : Panel { public BufferedPanel() { DoubleBuffered = true; } } 

Alternativamente, puede utilizar:

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

Para obtener el efecto idéntico , es decir , son equivalentes .

Cómo evitarlos en el nivel de formulario

La técnica anterior reducirá el parpadeo en el nivel de control, lo que significa que cuando la forma se vuelva a dibujar, todos los controles ya no parpadearán. Pero la solución definitiva es reducir el parpadeo desde el nivel de formulario: cuando la forma se vuelve a dibujar, la forma y todos sus elementos secundarios tienen doble búfer.

Esto requiere anular CreateParams :

 protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED return cp; } } 

Resumen

SetStyle hace el trabajo en el nivel de control, y CreateParam en el nivel de formulario, y logra doble búfer para todo el control dentro del formulario.

Créditos:

@terrybozzlo, @Caramiriel, @HansPassant