C# graphics flickering

后端 未结 4 2008
慢半拍i
慢半拍i 2020-12-08 22:46

I am working on kind of drawing program but I have a problem with flickering while moving a mouse cursor while drawing a rubberband line. I hope you can help me to remove th

4条回答
  •  鱼传尺愫
    2020-12-08 23:33

    First don't use CreateGraphics() unless you absolutely have to. Bind an event handler to OnPaint and call Invalidate() when you want to refresh the surface.

    If you don't want it to flicker you'll need to double buffer your drawing surface. The easiest way to do this is to set your form's DoubleBuffered property to True.

    I would highly recommend if you plan on extending this to do your drawing to the PictureBox control. PictureBox is double-buffered by default and allows you to control your drawing region much more simply.

    In code:

    public partial class Form1 : Form
        {
        int xFirst, yFirst;
        Bitmap bm = new Bitmap(1000, 1000);
        Graphics bmG;
        Pen pen = new Pen(Color.Black, 1);
        bool draw = false;
    
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
            bmG = Graphics.FromImage(bm);
            bmG.Clear(Color.White);
        }
    
        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            xFirst = e.X;
            yFirst = e.Y;
            draw = true;
        }
    
        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            bmG.DrawLine(pen, xFirst, yFirst, e.X, e.Y);
            draw = false;
            Invalidate();
        }
    
        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (draw)
            {
                Invalidate();
            }
        }
    
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            if (draw) {
                e.Graphics.DrawImage(bm, 0, 0);
                e.Graphics.DrawLine(pen, xFirst, yFirst, e.X, e.Y);
            } else {
                e.Graphics.DrawImage(bm, 0, 0);
            }
        }
    }
    

    Edit:

    Another issue, you are creating a private Pen member. Pens (and Brushes, as well as many GDI+ objects) represent handles to unmanaged objects that need to be disposed otherwise your program will leak. Either wrap them in using statements (the preferred and exception-safe way) or explicitly dispose of them in the form's Dispose method.

    Alternatively in System.Drawing you can access some pre-built Pens and Brushes that don't need to be (and shouldn't be) disposed. Use them like:

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            if (draw) {
                e.Graphics.DrawImage(bm, 0, 0);
                e.Graphics.DrawLine(Pens.Black, xFirst, yFirst, e.X, e.Y);
            } else {
                e.Graphics.DrawImage(bm, 0, 0);
            }
        }
    

提交回复
热议问题