2008-10-08 19 views
9

Tengo una aplicación .net que he escrito en C#. En algunos formularios, frecuente los campos de visualización. En algunos casos, todos los campos del formulario (cuadros de texto, etiquetas, cuadro de imagen, etc.) cambian su valor. Además, la frecuencia de los cambios podría ser cada segundo. Sin embargo, actualmente hay un parpadeo horrible cada vez que se actualiza el formulario. ¿Cómo puedo detener el parpadeo? ¿Hay alguna manera de tal vez doble buffer? ¡Por favor ayuda!visual C# formulario actualización resultados en parpadeo

Respuesta

1

No investigaste esto bien. Hay una propiedad DoubleBuffered en cada formulario. Intenta configurar eso en verdadero. Si no has sobrecargado nada en la pintura de formularios, todo debería funcionar.

+0

Gracias! He pasado años buscando esto y estaba sentado frente a mí todo el tiempo. – GrandMasterFlush

7

la respuesta corta es

SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 

La respuesta larga es: ver MSDN o google

sólo por diversión, intente llamar Application.DoEvents() después de cada elemento se actualiza, y ver si el problema mejora o empeora ;-)

+0

No estoy seguro de que eso ayude. Parece que el problema es que los controles estándar parpadean, y OptimizedDoubleBuffer solo ayudará con los controles personalizados. –

+0

@ [Cameron MacFarland]: no se pierde nada con probar ... –

0

La aparición de imágenes fantasmas suele deberse a que se está ejecutando en un único hilo y se está deteniendo con las actualizaciones de campo para que el evento de pintura no se active. Una forma de solucionar esto sería poner el trabajo pesado en métodos asíncronos. Esto permitirá que el formulario se vuelva a pintar y actualice lo que sea necesario cuando vuelvan a llamar al método asincrónico.

4

Puede intentar llamar al this.SuspendLayout(); antes de comenzar su actualización y this.ResumeLayout (false); cuando haya terminado de establecer todos los valores de esta manera, debe evitar que el formulario escriba valores uno a la vez.

+1

SuspendLayout/ResumeLayout son para la supresión de eventos relacionados con la adición de controles y moviendo –

+1

correcta, los eventos solo previenen funciones de diseño de ser llamado varias veces al actualizar grandes grupos de controles. Como tales, estas funciones acelerarán el diseño pero no evitarán el parpadeo. Usarlos junto con Double Buffering dará mejores resultados. – Toji

1

Puede double buffer casi todas las ventanas de control de formularios, aunque la mayoría de las veces requiere que herede el control deseado y anule una propiedad protegida. Tenga en cuenta, sin embargo, que he pasado bastante tiempo con el mismo problema y todavía tengo que eliminar completamente el parpadeo en mis formas más complejas.

Si quieres ventanas verdaderamente sin parpadeos, sugiero mirar WPF.

5

Esto funcionó para mí.

http://www.syncfusion.com/faq/windowsforms/search/558.aspx

Básicamente se trata de derivados de control deseado y el establecimiento de los siguientes estilos.

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

tuve el mismo problema con OpenGLES, que es cómo encontré este hilo. por supuesto realizo u no están utilizando OGL, pero tal vez esto ayuda U de todos modos;)

protected override void OnPaintBackground(PaintEventArgs e) { }

3

Sé que esta pregunta es viejo, pero puede haber otras personas que se buscan en el futuro.

DoubleBuffering no siempre funciona bien.Para forzar el formulario para no parpadear en absoluto (pero a veces causa problemas de dibujo):

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

Para detener el parpadeo cuando un usuario cambia el tamaño de un formulario, pero sin estropear el dibujo de los controles (siempre que su nombre de formulario es "Form1 "):

int intOriginalExStyle = -1; 
bool bEnableAntiFlicker = true; 

public Form1() 
{ 
    ToggleAntiFlicker(false); 
    InitializeComponent(); 
    this.ResizeBegin += new EventHandler(Form1_ResizeBegin); 
    this.ResizeEnd += new EventHandler(Form1_ResizeEnd); 
} 

protected override CreateParams CreateParams 
{ 
    get 
    { 
     if (intOriginalExStyle == -1) 
     { 
      intOriginalExStyle = base.CreateParams.ExStyle; 
     } 
     CreateParams cp = base.CreateParams; 

     if (bEnableAntiFlicker) 
     { 
      cp.ExStyle |= 0x02000000; //WS_EX_COMPOSITED 
     } 
     else 
     { 
      cp.ExStyle = intOriginalExStyle; 
     } 

     return cp; 
    } 
} 

private void Form1_ResizeBegin(object sender, EventArgs e) 
{ 
    ToggleAntiFlicker(true); 
} 

private void Form1_ResizeEnd(object sender, EventArgs e) 
{ 
    ToggleAntiFlicker(false); 
} 

private void ToggleAntiFlicker(bool Enable) 
{ 
    bEnableAntiFlicker = Enable; 
    //hacky, but works 
    this.MaximizeBox = true; 
} 
+0

Esta es la mejor y, en mi opinión, la respuesta definitiva. – HydroPowerDeveloper

2

Usted puede simplemente reemplazar el control original con una costumbre que ha protegido la propiedad DoubleBuffered true. P.ej. para ListView sería algo como esto:

internal class DoubleBufferedListView : ListView { 

    public DoubleBufferedListView() 
     : base() { 
     this.DoubleBuffered = true; 
    } 

} 

Después de que acaba de visitas * .Designer.cs archivo y reemplazar todas las menciones de control nativo con éste.

P.S. En lugar de heredar de control que también puede establecer esta propiedad a través de la reflexión:

listView1.GetType().GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(lsvReport, true, null); 

no está limpio ni se recomienda pero no requiere cambios en los archivos * .Designer.cs.

2

También podría ser causada por su codificación, no la ausencia de doublebuffering. Vine aquí justo ahora con un problema similar, pero me di cuenta de que es porque:

  1. Establezco un marco para invisible cuando un elemento no está seleccionado.
  2. En entre selecciones del usuario, el índice se borra por el control ListView.
  3. Estoy obligado al evento SelectedIndexChanged

En otras palabras:

  • usuario hace clic en el punto 1
    ~ SelectedIndexChanged (1) hace clic
  • de articulos 2
    ~ SelectedIndexChanged (-1) < ---- Esto hace que el parpadeo
    ~ SelectedIndexChanged (2)

Entonces, ¿cuál es la solución? How to avoid thousands of needless ListView.SelectedIndexChanged events?

Cuestiones relacionadas