¿Cómo puedo establecer la propiedad DoubleBuffered
protegida de los controles en un formulario que está sufriendo de parpadeo?Cómo duplicar los controles .NET de buffer en un formulario?
Respuesta
Aquí hay una versión más genérica de Dummy's solution.
Podemos usar el reflejo para llegar a la propiedad DoubleBuffered protegida, y luego se puede establecer en true.
Nota: Debe pay your developer taxes y no use double-buffering if the user is running in a terminal services session (por ejemplo escritorio remoto) Este método de ayuda no se encenderá el doble buffer si la persona que 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);
}
public void EnableDoubleBuffering()
{
this.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint,
true);
this.UpdateStyles();
}
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 algo más de información sobre el uso de este en un servidor terminal.
Esto hace el truco. Lo convertí en una función auxiliar genérica y lo publiqué aquí. –
No es realmente para * on * un servidor de terminal, ya que ninguno de mis clientes ejecuta el software desde una sesión de escritorio remota. Pero deberías pagar los impuestos a tu desarrollador, y no quería publicar un código que no incluyera los impuestos. –
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 ampliar el control específico que desea al doble buffer y establecer la propiedad DoubleBuffered dentro del controlador del control.
Por ejemplo:
class Foo : Panel
{
public Foo() { DoubleBuffered = true; }
}
Estoy trabajando con un ListView dibujado por el propietario en una clase derivada. ¡Esto resolvió el problema perfectamente! –
No sé si hay inconvenientes, pero funcionó a la perfección. Mi control personalizado previamente heredado de "Control", y en cambio lo cambié para heredarlo de "Panel" y establecí DoubleBuffered en verdadero. Un cambio de dos líneas. El movimiento es fluido ... y la velocidad para dibujar una actualización parece mucho más rápida también. –
Antes de intentar el doble buffer, a ver si SuspendLayout()/ResumeLayout() resolver su problema.
Suspend/ResumeLayout no resuelve el problema del parpadeo al pintar. –
He encontrado 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. This little gem of a code snippetrealmente hace la diferencia, pruébalo en serio. Pasé mucho tiempo en busca de una solución que funcionó y finalmente encontró que :-)
El enlace está muerto ... –
Sí, lo sé ... He perdido ese código y no he podido encontrarlo en ningún otro lugar en Internet ... ¡lo siento! – ljs
Comprobar this thread
Repitiendo el núcleo de esta respuesta, se puede activar el indicador de estilo WS_EX_COMPOSITED en la ventana para conseguir tanto la forma como todos sus controles tienen doble buffer. 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.
Pega este código en tu clase 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 soporte de doble búfer de Winform es que la versión de Winform sólo funciona en un control en en el tiempo. 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.
Guau ... habla sobre la noche y el día; gran diferencia para mí usando este método. –
404-ED. –
+1 OMG. Un-be-freakin-lievable. Intenté cualquier otra solución mencionada aquí, y todavía parpadeaba como código morse. Siguió la magia negra simple descrita aquí, y nary un blip en la pantalla. ¡GRACIAS! –
nobugz obtiene el crédito por el método en su enlace, solo estoy volviendo a publicar. Añadir esta anulación para la Forma:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
Esto funcionó mejor para mí, en Windows 7 que estaba recibiendo grandes bloques negros que aparecen cuando se cambio el tamaño de una forma pesada de control. ¡Ahora el control rebota! Pero es mejor
Esto es lo mismo que la respuesta de @Hans Passant, pero +1 para poner el código aquí. –
Nobugz, el nick que utilicé en los foros de MSDN. –
método de extensión para encender el doble buffer dentro o fuera de 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);
Esto me causó una gran cantidadde 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 un montón de agujeros (excrementos) cuando se re-dimensionamiento/volver a dibujar un control que contiene varios otros controles.
me trataron WS_EX_COMPOSITED y WM_SETREDRAW pero nada funcionó hasta que use esto:
private void myPanel_SizeChanged(object sender, EventArgs e)
{
Application.DoEvents();
}
Sólo quería transmitirlo.
versión vb.net de esta solución bien ....:
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
- 1. Cómo recorrer todos los controles en un formulario, incluidos los controles en un subformulario - Access 2007
- 2. Controles de centrado dentro de un formulario en .NET (Winforms)?
- 3. ¿Cómo puedo obtener todos los controles de un formulario que incluye controles en cualquier contenedor?
- 4. ¿Cómo elimino todos los controles en un panel o formulario a la VEZ? C#
- 5. Cómo agregar controles dinámicamente al formulario ASP.NET?
- 6. Cómo convertir todos los controles en un formulario web aspx a un equivalente de solo lectura
- 7. Deshabilitar todos los controles de formulario en una página web
- 8. Cómo agregar controles mediante programación a un formulario en VB.NET
- 9. Excel VBA: Obtención de los valores de controles de formulario
- 10. ¿Cómo obtengo todos los controles de un formulario en Windows Forms?
- 11. ¿Cómo hago doble buffer en un Panel en C#?
- 12. Texto antialias en un formulario .NET transparente
- 13. Controles de Obout en C# .Net
- 14. Cómo insertar los mejores controles acoplados debajo de los controles acoplados superiores previewsly en un panel
- 15. cambiar el tamaño y ajustar los controles de formulario según el tamaño del formulario
- 16. Hacer todos los controles en un formulario de solo lectura de una vez
- 17. Tamaño automático de los controles en winform
- 18. ¿Cómo acceder a los métodos y controles de formulario de una clase en C#?
- 19. controles .Net cambio de tamaño entre los ordenadores
- 20. Cómo duplicar un archivo .xib?
- 21. ¿Cuál es la mejor manera de borrar todos los controles en un formulario C#?
- 22. ¿Existe alguna manera rápida de cambiar los tabindex en un formulario con muchos controles?
- 23. Un controlador de eventos para todos los controles en el formulario
- 24. Cómo cambiar automáticamente el tamaño de los controles de formulario con cambio en la resolución
- 25. ¿Cómo puedo obtener los controles de botón en el formulario de Windows - Panel
- 26. Cómo atrapar una tecla presionada en un formulario de C# .NET
- 27. iOS Controles para .NET (WPF)
- 28. ¿Cuál es la mejor manera de actualizar los controles de formulario de un hilo de trabajo?
- 29. Cómo actualizar los controles del método estático?
- 30. ¿Cómo preparo los controles en un TabItem en WPF?
Este código resolvió mi problema sin ninguna modificación. ¡Gracias! – Mykroft
Es curioso, creo que es aún más importante realizar una doble amortiguación cuando se hace de forma remota, para evitar el envío innecesario de un montón de vueltas por el cable. –
Es exactamente lo que no quieres. En una sesión de terminal, el sistema GDI puede enviar comandos (dibujar una línea aquí, dibujar un círculo aquí, rellenar aquí, etc.). El búfer doble se logra al dibujar todo en un mapa de bits y luego usar GDI para pintar todo su formulario como un mapa de bits. El envío de un mapa de bits sin comprimir a través del cable es * MUCHO * más lento que el envío de los comandos Origianl GDI. –