¿Cómo puedo configurar la propiedad protegida DoubleBuffered
de los controles en un formulario que sufre parpadeo?
Aquí hay una versión más genérica de solución de Dummy .
Podemos usar la reflexión para llegar a la propiedad protegida DoubleBuffered , y luego se puede establecer en verdadero .
Nota : Debería pagar sus impuestos de desarrollador y no se doble búfer si el usuario se está ejecutando en un sesión de servicios de terminal (por ejemplo, Escritorio remoto) Este método auxiliar no activará el almacenamiento en búfer doble 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);
}
Compruebe este hilo
Repitiendo el núcleo de esa respuesta, puede activar el indicador de estilo WS_EX_COMPOSITED en la ventana para obtener tanto el formulario como todos sus controles con doble búfer. 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 borra a la pantalla de un golpe. Hacer que parezca instantáneo a los ojos del usuario sin artefactos de pintura visibles. No está completamente libre de problemas, algunos renderizadores 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 el soporte de doble búfer de Winform es que la versión de Winform solo funciona en un control a la vez. Aún verá cada control individual Paint en sí. Lo que también puede parecer un efecto de parpadeo, especialmente si el rectángulo de control sin pintar contrasta mal con el fondo de la ventana.
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 el uso de esto en un servidor terminal.
public void EnableDoubleBuffering()
{
this.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint,
true);
this.UpdateStyles();
}
Una forma es extender el control específico que desea duplicar el búfer y establecer la propiedad DoubleBuffered dentro del ctor del control.
Por ejemplo:
class Foo : Panel
{
public Foo() { DoubleBuffered = true; }
}
Método de extensión para activar o desactivar el doble búfer 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 que DataGridView DoubleBuffered):
DataGridView _grid = new DataGridView();
// ...
_grid.MakeDoubleBuffered(true);
nobugz obtiene el crédito por el método en su enlace, solo estoy volviendo 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 apareciendo grandes bloques negros cuando cambio el tamaño de una forma pesada de control. ¡El control ahora rebota en su lugar! Pero es mejor.
Antes de intentar el doble búfer, vea si SuspendLayout ()/ResumeLayout () resuelve su problema.
Esto me causó un lote de dolor durante dos días con un control de terceros hasta que lo rastreé.
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
Recientemente tuve muchos agujeros (excrementos) al redimensionar/volver a dibujar un control que contiene varios otros controles.
Intenté WS_EX_COMPOSITED y WM_SETREDRAW pero nada funcionó hasta que usé esto:
private void myPanel_SizeChanged(object sender, EventArgs e)
{
Application.DoEvents();
}
Solo quería transmitirlo.
versión vb.net de esta excelente solución ....:
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
También puede heredar los controles en sus propias clases y establecer la propiedad allí. Este método también es bueno si tiendes a hacer muchas configuraciones que son las mismas en todos los controles.
He descubierto que simplemente establecer la configuración de DoubleBuffered en el formulario establece automáticamente todas las propiedades enumeradas aquí.