How to fix Panel flashing (Flickering control) when drawing something?
I made an example when this happens pisca-pisca
, just put the control Panel
in the form and execute.
public Form1()
{
InitializeComponent();
this.KeyDown += Form1_KeyDown;
this.KeyPress += Form1_KeyPress;
this.panel1.Paint += panel1_Paint;
rectangle = new Rectangle()
{
Width = 20,
Height = 20,
};
}
Rectangle rectangle;
Keys keys;
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
keys = e.KeyCode;
}
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
this.panel1.Invalidate();
switch (keys)
{
case Keys.D:
{
rectangle.X += 10;
}
break;
case Keys.A:
{
rectangle.X -= 10;
}
break;
case Keys.W:
{
rectangle.Y -= 10;
}
break;
case Keys.S:
{
rectangle.Y += 10;
}
break;
default:
break;
}
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillRectangle(new SolidBrush(Color.Red), rectangle);
e.Graphics.DrawRectangle(new Pen(Color.Blue, 10), this.panel1.ClientRectangle);
}
You can notice that when you press one of the Keys
above, the edge of the Panel
and even the retângulo
itself flashes simultaneously.
When this happened in Form
, I would give the following command:
this.DoubleBuffered = true;
Then stopped flashing, but in the panel does not have that. What to do?
1 answers
This is an old problem of Windows Forms applications, what happens is that the graphical processing of the screen can not properly load the update of the screen, because the action taken is faster than the loading of the screen itself.
There are a number of Microsoft articles and solutions that promise to solve the problem, plus each case is a case, because it depends a lot on the amount of graphics you have in your form and also the amount of virtual memory available for the graphic processing of your computer.
Below is a compilation of links and a solution that solves 80% of the cases where Flickering happens.
Links important:
Https://stackoverflow.com/questions/8046560/how-to-stop-flickering-c-sharp-winforms
My solution:
- Configure your form with the DoubleBuffered option;
- put the code below in the inside of your form constructor:
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
- include this code snippet in your Form:
protected override CreateParams CreateParams { get { CreateParams handleParam = base.CreateParams; handleParam.ExStyle |= 0x02000000; return handleParam } }
So your code would look like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.KeyDown += Form1_KeyDown;
this.KeyPress += Form1_KeyPress;
this.panel1.Paint += panel1_Paint;
rectangle = new Rectangle()
{
Width = 20,
Height = 20,
};
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
protected override CreateParams CreateParams
{
get
{
CreateParams handleParam = base.CreateParams;
handleParam.ExStyle |= 0x02000000;
return handleParam;
}
}
Rectangle rectangle;
Keys keys;
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
keys = e.KeyCode;
}
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
this.panel1.Invalidate();
switch (keys)
{
case Keys.D:
rectangle.X += 10;
break;
case Keys.A:
rectangle.X -= 10;
break;
case Keys.W:
rectangle.Y -= 10;
break;
case Keys.S:
rectangle.Y += 10;
break;
default:
break;
}
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillRectangle(new SolidBrush(Color.Red), rectangle);
e.Graphics.DrawRectangle(new Pen(Color.Blue, 10), this.panel1.ClientRectangle);
}
}