How to Double Buffer .Net Controls on a Form

How do I enable double-buffering of a control using C# (Windows forms)?

In the constructor of your control, set the DoubleBuffered property, and/or ControlStyle appropriately.

For example, I have a simple DoubleBufferedPanel whose constructor is the following:

this.DoubleBuffered = true;
this.SetStyle(ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.ContainerControl |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.SupportsTransparentBackColor
, true);

How to double buffer .NET controls on a form?

Here's a more generic version of Dummy's solution.

We can use reflection to get at the protected DoubleBuffered property, and then it can be set to true.

Note: You should pay your developer taxes and not use double-buffering if the user is running in a terminal services session (e.g. Remote Desktop) This helper method will not turn on double buffering if the person is running in remote desktop.

public static void SetDoubleBuffered(System.Windows.Forms.Control c)
{
//Taxes: Remote Desktop Connection and painting
//http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
if (System.Windows.Forms.SystemInformation.TerminalServerSession)
return;

System.Reflection.PropertyInfo aProp =
typeof(System.Windows.Forms.Control).GetProperty(
"DoubleBuffered",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);

aProp.SetValue(c, true, null);
}

Double buffering with Panel

I should have posted my solution a long time ago...

Well, here is my solution:

Bitmap buffer = new Bitmap(screenWidth, screenHeight);//set the size of the image
System.Drawing.Graphics gfx = Graphics.FromImage(buffer);//set the graphics to draw on the image
drawStuffWithGraphicsObject(gfx);//draw
pictureBox1.Image = buffer;//set the PictureBox's image to be the buffer

Makes me feel like a complete idiot for finding this solution years after asking this question.

I have tried this with a Panel, but it has proven to be slower when applying the new image. Somewhere I had read, that it is better to use Panel instead of PictureBox. I don't know if I have to add something to the code to speed things up for the Panel, though.

How do I enable double-buffering on the Windows Forms StatusBar?

The System.Windows.Forms.StatusBar is a legacy control, it might not care about the DoubleBuffered property. You can try setting it like so in the constructor of a derived class:

this.SetStyle(ControlStyles.DoubleBuffer, true);

Although I would really recommend trying the StatusStrip control. It's made for Windows Forms and not drawn by the OS while the StatusBar is.

Can't draw on double buffered form


using (Graphics g = e.Graphics)

The using keyword is the bug in this code. In essence it killed the double-buffer and the normal painting cycle cannot continue. Where "normal" is the content of the buffer getting blitted to the screen after your OnPaint() method completes. This screws up both the rendering of the background, which is why you see the back of the monitor, and the foreground, the image you drew.

Golden rule for using (or calling Dispose) is that you should only ever do that when you created the object. If you didn't, like you did not in this case, then you cannot assume that you "own" the object and you have to rely on the caller of your code to take care of it. Which it does, no need to help.

Fix:

e.Graphics.DrawImage(player.Sprite, new Rectangle(player.X, player.Y, 20, 20));
base.OnPaint(e);

Enabling Double Buffering

Control.DoubleBuffering performs

SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, value);

so your code sets ControlStyles.UserPaint as well (which probably has no effect at this point).



Related Topics



Leave a reply



Submit