¿Cómo duplicar los controles .NET en un formulario?
-
09-06-2019 - |
Pregunta
¿Cómo puedo configurar el protegido? DoubleBuffered
¿Propiedad de los controles en un formulario que sufre parpadeo?
Solución
Aquí hay una versión más genérica de La solución del muñeco.
Podemos usar la reflexión para llegar a lo protegido. Doble buffer propiedad, y luego se puede establecer en verdadero.
Nota:Debería paga tus impuestos de desarrollador y no use doble almacenamiento en búfer si el usuario se está ejecutando en una sesión de servicios de terminal (p.ej.Escritorio remoto) Este método auxiliar no activará el doble almacenamiento en búfer si la persona está ejecutando en un 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);
}
Otros consejos
Controlar este hilo
Repitiendo el núcleo de esa respuesta, puede activar el indicador de estilo WS_EX_COMPOSITED en la ventana para que tanto el formulario como todos sus controles tengan doble búfer.La bandera de estilo está disponible desde XP.No hace que pintar sea más rápido, pero toda la ventana se dibuja en un búfer fuera de la pantalla y se muestra en la pantalla de un solo golpe.Haciendo 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 buffer de Winform es que la versión de Winform sólo funciona en un control a la vez.Aún verás que cada control individual se pinta.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; }
}
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 aparecían grandes bloques negros cuando cambiaba el tamaño de un formulario de control pesado.¡El control ahora rebota!Pero es mejor.
Método de extensión para activar o desactivar el doble buffer 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 sea DoubleBuffered):
DataGridView _grid = new DataGridView();
// ...
_grid.MakeDoubleBuffered(true);
Antes de intentar el doble buffer, vea si SuspendLayout()/ResumeLayout() resuelve su problema.
Esto me causó un lote de duelo durante dos días con el control de un tercero hasta que lo localicé.
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
Recientemente tuve muchos agujeros (excrementos) al cambiar el tamaño/redibujar un control que contiene varios otros controles.
Probé WS_EX_COMPOSITED y WM_SETREDRAW pero nada funcionó hasta que usé esto:
private void myPanel_SizeChanged(object sender, EventArgs e)
{
Application.DoEvents();
}
Sólo 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 realizar muchas configuraciones que son iguales en todos los controles.
Descubrí que simplemente configurar la configuración DoubleBuffered en el formulario establece automáticamente todas las propiedades enumeradas aquí.