3

This is my code. When I move cursor over Form it works, circle is moving but it is blinking. How can I fix this?

public partial class Preprocesor : Form
{
    int x, y;
    Graphics g;

    public Preprocesor()
    {
        InitializeComponent();
    }

    private void Preprocesor_Load(object sender, EventArgs e)
    {
        g = pnlMesh.CreateGraphics();
    }

    private void pnlMesh_Paint(object sender, PaintEventArgs e)
    {
        g.Clear(Color.White);
        g.FillEllipse(Brushes.Black, x, y, 10, 10);
    }

    private void pnlMesh_MouseMove(object sender, MouseEventArgs e)
    {
        x = e.X;
        y = e.Y;
        pnlMesh.Invalidate();
    }
}
Eric
  • 11,392
  • 13
  • 57
  • 100
Ichibann
  • 4,371
  • 9
  • 32
  • 39
  • why do you need to create `Graphics` here? PaintEventArgs already supplied a graphics method. – Rye Jan 23 '11 at 23:16

2 Answers2

5

You need to draw on a double-buffered control.

Make a class that inherits Control and sets DoubleBuffered = true; in the constructor (this is a protected property).
Use that control instead of your panel it there won't be any flickering.

Also, you should not store a Graphics object for later.
Instead, you should draw on e.Graphics in the Paint handler.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Thanx. That works :). Except I made control that inherits `Panel` – Ichibann Jan 23 '11 at 23:07
  • @Ichibann: Unless you're also putting controls inside of it, you shouldn't use a panel; it just adds overhead. – SLaks Jan 23 '11 at 23:10
  • +1 just one small comment - before using this double buffer I used to dispose the `e.Graphics` object every time which didn't cause any problems, but with the double buffer set to true, it caused that nothing was painted. Removed the dispose and all works like a charm.. – Shadow The GPT Wizard Dec 13 '11 at 14:57
  • @ShadowWizard: You should not dispose an object that belongs to someone else unless the documentation tells you to. – SLaks Dec 13 '11 at 14:58
  • @SLaks I didn't know that when writing the original code, wasn't sure until you said it, always fearing that behind the scenes it returns new Graphics object that have to be disposed. Maybe due to my SharePoint background - anyway, thanks for clarifying. – Shadow The GPT Wizard Dec 13 '11 at 18:11
  • It is a new Graphics object, but it's owned and disposed by Windows. – SLaks Dec 13 '11 at 22:16
4

How bout overriding a panel user control and set Doublebuffered to true?

public partial class BufferPanel : Panel
{
    public BufferPanel()
    {
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        UpdateStyles();
    }
}
Rye
  • 2,273
  • 9
  • 34
  • 43