I have a problem with the Label control that is terribly flickering.
Below is some code to reproduce the problem.
How to solve this?
UPDATE: The solution for the previous case (a Form contains a Label directly) was to make the form.DoubleBuffered = true. But this is not a generic solution. For example, what should I do in the case of label inside a SplitContainer? this is my real case.
UPDATED CODE:
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());
}
}
}
The problem is with the docking. If you change the Label.Dock from Fill to None, manually set the size of the label to fill the split panel and then anchor it on all sides, it won't flicker.
If you want to see the cause of the flicker, while Dock is still set to Fill, override OnResize in your DoubleBufferedLabel class, start the application, and while it is running set a breakpoint in OnResize. Add a watch for the Size and you'll see it flipping between its design time and runtime sizes.
I tried using a regular SplitContainer and Label in your example, set DoubleBuffer to False on the form, and it did not flicker if I left Dock set to None on the Label.
Paste this into your form code to help the Dock layout calculations:
protected override void OnLoad(EventArgs e) {
label1.Size = this.ClientSize;
base.OnLoad(e);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With