Pregunta

Tengo un problema con el control de etiqueta que está terriblemente parpadea.

A continuación se muestra un código para reproducir el problema.

¿Cómo resolver esto?

UPDATE: La solución para el caso anterior (un formulario contiene una etiqueta directamente) era hacer que el form.DoubleBuffered = verdadero. Pero esto no es una solución genérica. Por ejemplo, ¿qué debo hacer en el caso de una etiqueta dentro SplitContainer? este es mi verdadero caso.

código actualizado:

DoubleBufferedLabel.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace FlickerLabelTest
{
    public class DoubleBufferedLabel : Label
    {
        public DoubleBufferedLabel()
        {
            DoubleBuffered = true;
        }
    }
}

DoubleBufferedSplitContainer.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace FlickerLabelTest
{
    public class DoubleBufferedSplitContainer : SplitContainer
    {
        public DoubleBufferedSplitContainer()
        {
            DoubleBuffered = true;
        }
    }
}

Form1.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

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

        private void timer1_Tick(object sender, EventArgs e)
        {
            label1.Text += "0";
        }
    }
}

Form1.Designer.cs:

namespace FlickerLabelTest
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.label1 = new FlickerLabelTest.DoubleBufferedLabel();
            this.splitContainer1 = new DoubleBufferedSplitContainer();
            this.splitContainer1.Panel2.SuspendLayout();
            this.splitContainer1.SuspendLayout();
            this.SuspendLayout();
            // 
            // timer1
            // 
            this.timer1.Enabled = true;
            this.timer1.Interval = 1;
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            // 
            // label1
            // 
            this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.label1.Location = new System.Drawing.Point(0, 0);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(186, 262);
            this.label1.TabIndex = 0;
            this.label1.Text = "label1";
            // 
            // splitContainer1
            // 
            this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.splitContainer1.Location = new System.Drawing.Point(0, 0);
            this.splitContainer1.Name = "splitContainer1";
            // 
            // splitContainer1.Panel2
            // 
            this.splitContainer1.Panel2.Controls.Add(this.label1);
            this.splitContainer1.Size = new System.Drawing.Size(284, 262);
            this.splitContainer1.SplitterDistance = 94;
            this.splitContainer1.TabIndex = 1;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 262);
            this.Controls.Add(this.splitContainer1);
            this.DoubleBuffered = true;
            this.Name = "Form1";
            this.Text = "Form1";
            this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
            this.splitContainer1.Panel2.ResumeLayout(false);
            this.splitContainer1.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Timer timer1;
        private DoubleBufferedLabel label1;
        private DoubleBufferedSplitContainer splitContainer1;
    }
}

Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace FlickerLabelTest
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
¿Fue útil?

Solución

El problema es con el acoplamiento. Si cambia el Label.Dock de Fill a None, ajustar manualmente el tamaño de la etiqueta para llenar el panel de división y luego anclarlo en todos los lados, no lo hará parpadeo.

Si quieres ver la causa del parpadeo, mientras Dock fotografías está ajustado a Fill, OnResize anulación de su clase DoubleBufferedLabel, inicie la aplicación, y mientras se está ejecutando establece un punto de interrupción en OnResize. Añadir un reloj para la Size y verá que mover de un tirón entre sus tiempo de ejecución y diseño de tamaños.

Me trató de usar su SplitContainer regular y Label en su ejemplo, conjunto DoubleBuffer a False en el formulario, y no lo hizo parpadeo si dejaba conjunto Dock a None en el Label.

Otros consejos

pega esto en el código del formulario para ayudar a los cálculos de diseño Muelle:

    protected override void OnLoad(EventArgs e) {
        label1.Size = this.ClientSize;
        base.OnLoad(e);
    }

No es realmente una respuesta, pero ¿por qué desea actualizar su etiqueta cada milisegundo ? Si nos referimos 1 segundo, tendría que configurar su intervalo de 1000.

Se puede resolver este dando el tiempo para volver a dibujar la forma en sí y usando un intervalo mayor.

Actualización: resultado, el ajuste de DoubleBuffered para soluciona el problema verdadero. Gracias por csharptest.net por señalar esto y DxCK por corregirme.

creo que estás buscando este: http: // MSDN. microsoft.com/en-us/library/3t7htc9c.aspx

ejemplo:

class Form1 : Form
{
   public Form1() {
      this.DoubleBuffered = true;
   }
}

Detener el establecimiento de temporizadores a 1 ms. No, en serio, lo que se ve aquí es que la etiqueta intenta continuar con ella de cambios, pero no lo hace porque son frecuentar. Así posibles soluciones son:

  • Selecciona una manera de cambiar la etiqueta con menos frecuencia
  • Activar doble búfer en el formulario

¿Por qué no ejecutar su función de actualización a través de un delegado de la etiqueta asíncrona? O espacio de nombres para el uso System.Threading un sabor diferente.

Además, ya que la gente delante de mí mencionados, sería útil si se establece la propiedad DoubleBuffer en su forma como verdadero (no es ninguna bala de plata sin embargo).

Activación de doble búfer en el formulario se solucionará el problema. Pero que en realidad es una solución cara. Si sólo tiene que añadir lo siguiente al formulario:

 SetStyle(ControlStyles.AllPaintingInWmPaint, true);

el parpadeo será más también.

El comportamiento predeterminado del sistema operativo Windows que primero dejó todas las ventanas pintan su fondo, y después, dejar que ellos hagan pintura real. Este es de los viejos tiempos, cuando las letras pintura realmente tuvieron una considerable cantidad de tiempo. Esta bandera indica que debe doblar el fondo de pintura y la pintura regular (por la misma ventana) inmediatamente después de la otra.

Propiedades doble buffer puede reservarse para los casos en los que de hecho ya pintar a sí mismo (cuando se reemplaza OnPaint).

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