c# winforms flicker doublebuffered

c# - ¿Cómo duplicar los controles.NET de buffer en un formulario?



winforms flicker (12)

¿Cómo puedo establecer la propiedad DoubleBuffered protegida de los controles en un formulario que sufren de parpadeo?


Antes de probar el doble almacenamiento en búfer, vea si SuspendLayout () / ResumeLayout () resuelve su problema.


Aquí hay una versión más genérica de la solución de Dummy .

Podemos usar el reflejo para acceder a la propiedad DoubleBuffered protegida, y luego puede establecerse en verdadero .

Nota : debe pagar los impuestos de su desarrollador y no utilizar el doble almacenamiento si el usuario se está ejecutando en una sesión de servicios de terminal (por ejemplo, Escritorio remoto). Este método de ayuda no activará el doble almacenamiento si la persona se está ejecutando en el escritorio remoto.

public static void SetDoubleBuffered(System.Windows.Forms.Control c) { //Taxes: Remote Desktop Connection and painting //http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx if (System.Windows.Forms.SystemInformation.TerminalServerSession) return; System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control).GetProperty( "DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); aProp.SetValue(c, true, null); }


Descubrí que simplemente estableciendo la configuración DoubleBuffered en el formulario establece automáticamente todas las propiedades enumeradas aquí.

Sin embargo; He encontrado que el doble buffer proporcionado por winforms es menos que excelente. Esta pequeña joya de fragmento de código realmente hace la diferencia, pruébalo en serio. Pasé mucho tiempo buscando una solución que funcionara y finalmente encontré eso :-)


Esto me causó mucha pena durante dos días con el control de un tercero hasta que lo rastreé.

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

Recientemente tuve muchos agujeros (excrementos) cuando volví a dimensionar / redibujar un control que contenía varios otros controles.

Intenté WS_EX_COMPOSITED y WM_SETREDRAW pero nada funcionó hasta que utilicé esto:

private void myPanel_SizeChanged(object sender, EventArgs e) { Application.DoEvents(); }

Solo quería pasarlo.


También puede heredar los controles en sus propias clases y establecer la propiedad allí. Este método también es bueno si tiende a hacer muchas configuraciones que son iguales en todos los controles.


Una forma es extender el control específico que desea duplicar el búfer y establecer la propiedad DoubleBuffered dentro del controlador del control.

Por ejemplo:

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


Verifique este hilo

Repitiendo el núcleo de esa respuesta, puede activar el indicador de estilo WS_EX_COMPUESTO en la ventana para obtener tanto el formulario como todos sus controles con búfer doble. La bandera de estilo está disponible desde XP. No hace que la pintura sea más rápida, pero toda la ventana se dibuja en un búfer fuera de la pantalla y se enfoca en la pantalla de una sola vez. Hacer que se vea instantáneamente a los ojos del usuario sin artefactos de pintura visibles. No es completamente libre de problemas, algunos visualizadores de estilos visuales pueden fallar, particularmente TabControl cuando tiene demasiadas pestañas. YMMV.

Pegue este código en su clase de formulario:

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

La gran diferencia entre esta técnica y la compatibilidad con doble buffer de Winform es que la versión de Winform solo funciona en un control a la vez. Todavía verá cada pintura de control individual. También puede parecer un efecto de parpadeo, particularmente si el rectángulo de control sin pintar contrasta mal con el fondo de la ventana.


vb.net versión de esta solución fina ....:

Protected Overrides ReadOnly Property CreateParams() As CreateParams Get Dim cp As CreateParams = MyBase.CreateParams cp.ExStyle = cp.ExStyle Or &H2000000 Return cp End Get End Property


nobugz obtiene el crédito por el método en su enlace, solo lo vuelvo a publicar. Agregue esta anulación al formulario:

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

Esto funcionó mejor para mí, en Windows 7 estaba obteniendo grandes bloques negros que aparecen cuando cambio el tamaño de una forma pesada de control. ¡Ahora el control rebota! Pero es mejor


Método de extensión para activar o desactivar el doble almacenamiento en memoria intermedia para los controles

public static class ControlExtentions { /// <summary> /// Turn on or off control double buffering (Dirty hack!) /// </summary> /// <param name="control">Control to operate</param> /// <param name="setting">true to turn on double buffering</param> public static void MakeDoubleBuffered(this Control control, bool setting) { Type controlType = control.GetType(); PropertyInfo pi = controlType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); pi.SetValue(control, setting, null); } }

Uso (por ejemplo, cómo hacer DataGridView DoubleBuffered):

DataGridView _grid = new DataGridView(); // ... _grid.MakeDoubleBuffered(true);


System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control) .GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); aProp.SetValue(ListView1, true, null);

Ian tiene más información sobre cómo usar esto en un servidor de terminal.


public void EnableDoubleBuffering() { this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); this.UpdateStyles(); }