C#, double buffer in WinForms?

蹲街弑〆低调 提交于 2019-12-13 17:09:56

问题


        private void button3_Click(object sender, EventArgs e)
    {

        this.DoubleBuffered = true;

            for (int i = 0; i < 350; i++)
            {
                using (Graphics g = this.CreateGraphics() )
                {
                    g.Clear(Color.CadetBlue);
                    g.DrawImage(Properties.Resources._256, 100, 100, i-150, i-150);
                }
            }
    }

Yet thought I have the DoubleBuffered set to true, the image still flickers. Any ideas what am I doing wrong? Thanks!


回答1:


As Neil noted, you don't need to (and shouldn't) create a new Graphics object in each iteration of the loop. These are relatively expensive resources and should not be created willy nilly.

Also, you shouldn't be painting like that inside of a button Click handler by calling CreateGraphics. It can lead to problems, most notably your drawing being "undone" when the paint handler is invoked (i.e., every time the window is receives a WM_PAINT message and is refreshed). You should do all of your painting by overriding OnPaint and simply call Invalidate() when you need to update your form.

As for the flickering, setting DoubleBuffered to true will usually take care of it, but rolling your own double buffering is trivial. Give it a try. Also realize that drawing in a loop like that probably isn't what you want to do. Use a timer if you want to update once per some interval. Your code is being executed as fast as the loop can execute, which is not usually desirable.

private void someTimer_Tick( ... )
{
    Invalidate();
}
protected override void OnPaint( PaintEventArgs e )
{
    using( var tempBmp = new Bitmap( ... ) )
    using( var g = Graphics.FromImage( tempBmp ) )
    {
        // draw to tempBmp
        e.Graphics.DrawImage( tempBmp, new Point( 0, 0 ) );
    }
}



回答2:


The problem is you are creating a new graphics object on each iteration of the loop

Move the for statement within the using statement, and you should see a dramatic performance increase:

using (Graphics g = this.CreateGraphics() )
{
     for (int i = 0; i < 350; i++)
     {
        g.Clear(Color.CadetBlue);
        g.DrawImage(Properties.Resources._256, 100, 100, i-150, i-150);
     }
}

That, and it may also be a good idea to move the Resource file you are loading into a local variable.




回答3:


Double-buffering is only enabled for the Paint event. You are directly drawing to the screen with CreateGraphics(), the g.Clear() call is very noticeable since it instantly erases the drawn image. Not drawing in the Paint event or OnPaint method is almost always a mistake.



来源:https://stackoverflow.com/questions/5095221/c-double-buffer-in-winforms

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!