2009-08-26 19 views
18

Hay muchos artículos que tratan el parpadeo en Windows Forms. La mayoría recomienda establecer DoubleBuffered = true o establecer un grupo de indicadores ControlStyle. Sin embargo, ninguno de estos ayuda a reducir el parpadeo de un cuadro de texto.Cómo evitar que un TextBox de Windows Forms parpadee al redimensionar?

Aquí hay un par de preguntas relacionadas:

Para reproducir el problema, cree un nuevo proyecto de Windows Forms, añadir un TextBox, permiten multilínea, deshabilitar ajuste de texto, agregar un montón de texto, establecer Anchor a la izquierda + derecha + arriba + abajo. Ahora ejecuta y cambia el tamaño. El texto parpadea. Para los cuadros de texto dentro de un par de TableLayoutPanel s anidados, el parpadeo al cambiar el tamaño es aún peor.

Aplicando las soluciones propuestas en las preguntas anteriores, en el mejor de los casos no arregla el parpadeo; si soy experimental y configuro el ControlStyle protegido en TextBox, puedo romperlo completamente (habilitando UserPaint) pero no eliminar el parpadeo.

Entonces, ¿hay alguna manera de arreglar el parpadeo del texto en un TextBox?

+1

Publicación interesante, tengo problemas similares con el control de una etiqueta, pero sobre la base de que leo DoubleBuffer solo debe establecerse con AllPaintInWmPaint, que solo se debe establecer con UserPaint, no lo guardé doblemente ... – Ian

+0

@romkyns, he actualizado mis ans wer con una solución que he usado en el pasado. – Ash

Respuesta

15

por lo general uso un RichTextBox en lugar de un cuadro de texto de varias líneas. Al configurar las propiedades DetectUrls- y ShortcutsEnabled-false, el RTB se comporta de forma muy similar a un TextBox y ... es sin parpadeo.

+0

Esta es definitivamente la solución más rápida y fácil. Tomé un control personalizado basado en TextBox y simplemente cambié el padre a RichTextBox y - problema resuelto. – Andy

+0

¿Cómo no fue esta la respuesta aceptada? Es completamente exacto, gracias! (Por supuesto, no ayudaría a parpadear los problemas de los controles secundarios que no eran cuadros de texto, pero esa no era la pregunta). – neminem

0

Hemos encontrado el mismo tipo de problema en el pasado y resulta en el uso excesivo de paneles de acoplamiento y disposición de tablas. Sugeriré, si es posible, intentar reconstruir la IU con un uso mínimo de acoplamiento (ya que el panel de diseño de la tabla también utiliza el acoplamiento interno).

+0

También he observado que el parpadeo empeora a medida que aumenta el número de controles relacionados con el diseño. Desafortunadamente todavía hay parpadeo, incluso con la distribución mínima necesaria para lograr el cambio de tamaño básico, como en mi ejemplo. –

4

En Windows Forms, la propiedad DoubleBuffered no afecta a los controles secundarios, como los cuadros de texto. En cambio, afecta solo la forma o el Panel para el que está configurado.

Si desea duplicar el almacenamiento en búfer para los elementos secundarios en un formulario, deberá implementar el doble almacenamiento en el buffer manual.

Bob Powell ha escrito good article (y otros) sobre cómo hacer esto.

También, a partir de una forum answer Bob también dice:

La propiedad de una ventana significa que van a parpadear sin control porque no se puede hacer doble búfer fuera del área de ventanas de destino. Un panel con controles secundarios no puede ser hecho para duplicar el propio buffer y es hijos por ejemplo.

La única manera de hacer esto correctamente es para crear un único control que hace todo el dibujo mediante una forma de sistema de modo de gráficos conservado.

Por lo tanto, para obtener el parpadeo de texto libre de cambiar el tamaño utilizando el doble buffer manual de lo que se necesita para hacer de alguna manera el cuadro de texto a su memoria intermedia hacia atrás y luego mostrarlo como parte de la actualización tamponada. Si es posible, no espero que esto sea fácil.

[Actualización]

Algunas otras respuestas han dicho que este es un problema con Windows Forms específicamente. Esto no es correcto, en realidad es más profundo que eso y es causado por Windows GDI. Como ejemplo, abra el Bloc de notas/Wordpad, etc. y pegue una gran cantidad de texto, cambie el tamaño de la ventana y observe el mismo problema de parpadeo.

Aquí hay una solución básica que utilicé hace años para hacer algo similar. Es un formulario simple que contiene un cuadro de texto multilínea y una clase personalizada que hereda del Panel. Ambos controles tienen la misma ubicación y tamaño. Utiliza las formas ResizeBegin y ResizeEnd para mostrar el panel al redimensionar, y el cuadro de texto de lo contrario. No es perfecto pero elimina el parpadeo.

public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     Bitmap bm = null; 

     private void textBox1_Resize(object sender, EventArgs e) 
     { 

      Graphics g = textBox1.CreateGraphics(); 

      if (g.VisibleClipBounds.IsEmpty == false) 
      { 
       bm = new Bitmap((int)g.VisibleClipBounds.Width, (int)g.VisibleClipBounds.Height); 

       textBox1.DrawToBitmap(bm, new Rectangle(0, 0, (int)g.VisibleClipBounds.Width, (int)g.VisibleClipBounds.Height)); 

      } 

      g.Dispose(); 


     } 

     private void panelDB1_Paint(object sender, PaintEventArgs e) 
     { 
      if (bm != null) 
      { 
       e.Graphics.DrawImageUnscaled(bm, 0, 0,bm.Width,bm.Height); 
      } 
     } 

     private void Form1_ResizeBegin(object sender, EventArgs e) 
     { 
      panelDB1.BringToFront(); 
     } 

     private void Form1_ResizeEnd(object sender, EventArgs e) 
     { 
      panelDB1.SendToBack(); 
     } 
} 

class PanelDB : Panel 
{ 
    public PanelDB() 
    { 
     this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer,true);  
     //this.DoubleBuffered = true; 

    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 
    } 
} 
+0

Gracias. El artículo podría ser útil para personas que no están familiarizadas con las técnicas de doble buffer, pero realmente no ayuda a abordar la cuestión. En cuanto a la propiedad de las ventanas, tengo la sensación de que el TextBox nativo en Windows es inherentemente flickery y esto no se puede corregir sin hacks extremos ... –

+0

He agregado una actualización a mi pregunta. Lamentablemente, la respuesta a su pregunta es simplemente "usted no puede", sin embargo, creo que alguna información de fondo sería útil. – Ash

+0

Al verificar parte de mi código anterior, veo que es simple renderizar un cuadro de texto sin parpadeo, utilizando el método DrawToBitmap() en un mapa de bits en la memoria. Pero esto simplemente crearía una imagen en pantalla de su cuadro de texto que nunca parpadea al cambiar el tamaño, pero es totalmente inútil ya que no le permite ingresar texto. – Ash

-2

FUNCIÓN LockWindow AS LONG control Enviar ghDlg,% TEXT_UPPER,% WM_SETREDRAW, 0,0 CLEARBuffers End Function

FUNCIÓN UnlockWindow AS LONG ClearBuffers control Enviar ghDlg,% TEXT_UPPER,% WM_SETREDRAW, 1, 0 FIN FUNCIÓN

Cuestiones relacionadas