Cómo evitar que un cuadro de texto de Windows Forms de parpadeo en cambio de tamaño?

StackOverflow https://stackoverflow.com/questions/1333393

  •  20-09-2019
  •  | 
  •  

Pregunta

Hay un montón de artículos que tratan parpadeo en Windows Forms. La mayoría recomienda configurar DoubleBuffered = true o la creación de un grupo de banderas ControlStyle. Sin embargo, ninguno de estos ayudan a reducir el parpadeo de un cuadro de texto.

Aquí hay un par de preguntas relacionadas:

Para reproducir el problema, cree un nuevo proyecto de Windows Forms, añadir un TextBox, permitirá multilínea, desactivar word-wrap, añadir un montón de texto, establecer Anchor a Izquierda + Derecha + Top + Bottom. Ahora corre y cambiar el tamaño. El texto parpadea. Para cuadros de texto dentro de un par de TableLayoutPanels anidados los temblores de cambio de tamaño es aún peor.

La aplicación de las soluciones propuestas en las preguntas anteriores, en el mejor no se soluciona el parpadeo; si consigo experimental y puse el ControlStyle protegida en TextBox puedo romper por completo (al permitir UserPaint) pero no eliminar el parpadeo.

Así que, ¿hay alguna manera en absoluto a solucionar el parpadeo del texto en un cuadro de texto?

¿Fue útil?

Solución

Yo suelo usar un RichTextBox en lugar de un cuadro de texto de varias líneas. Al establecer los DetectUrls- y ShortcutsEnabled-propiedades en falso el RTB comporta de forma muy similar a un cuadro de texto y ... es sin parpadeos .

Otros consejos

En Windows Forms DoubleBuffered la propiedad no afecta a los controles secundarios tales como cuadros de texto. En su lugar, sólo afecta a la forma o el panel que se establece para.

Si desea búfer doble para los elementos secundarios de un formulario, tendrá que implementar el doble buffer manual.

Bob Powell ha escrito un buena artículo (y otros) sobre cómo hacer esto.

También, a partir de un respuesta foro Bob también dice:

  

La propiedad de una ventana significa que   van a parpadear sin control   porque no se puede doblar-buffer   fuera del área de ventanas de destino. UNA   panel con controles secundarios no puede ser   hecho a sí mismo búfer doble y   que es, por ejemplo, los niños.

     

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

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 aún posible, no espero que esto sería 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 causada por Windows GDI. A modo de ejemplo, el Bloc de notas abierta / Wordpad, etc y pegar una gran parte del texto, cambiar el tamaño de la ventana y observa el mismo problema de parpadeo.

Aquí es una solución básica que utilizó hace años para hacer algo similar. Es una forma simple que contiene un cuadro de texto de varias líneas y una clase personalizada que hereda de Panel. Ambos controles tienen la misma ubicación y tamaño. Utiliza las Formas ResizeBegin y ResizeEnd para mostrar el panel al cambiar el tamaño, y el cuadro de texto de otra manera. No es perfecto, pero sí 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);
    }
}

Hemos encontrado mismo tipo de problema en el pasado y que viene a ser el uso de paneles de conexión y la disposición de la tabla excesivas. Voy a sugerir, si es posible, tratar de volver a construir la interfaz de usuario con un uso mínimo de acoplamiento (como panel de presentación de la tabla también utiliza acoplamiento internamente).

Función LockWindow EL TIEMPO   Control Enviar ghDlg, TEXT_UPPER%, WM_SETREDRAW%, 0,0   CLEARBuffers FIN DE FUNCIONES

Función UnlockWindow EL TIEMPO   ClearBuffers   Control Enviar ghDlg, TEXT_UPPER%, WM_SETREDRAW%, 1,0 FIN DE FUNCIONES

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top