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
Copy Datagridview Values to Textbox
Calculate the Execution Time of a Method
How to Enable Cors in ASP.NET Core Webapi
Resizing an Image Without Losing Any Quality
Will Using 'Var' Affect Performance
How to Do Constructor Chaining in C#
Maximum Number of Threads in a .Net App
How to Connect to MySQL Database
How to Double Buffer .Net Controls on a Form
Distinct Not Working With Linq to Objects
How to Use C# 7 With Visual Studio 2015
Inconsistent Accessibility: Parameter Type Is Less Accessible Than Method
Is a Linq Statement Faster Than a 'Foreach' Loop
Deserialize Json to C# Classes
.Net Process.Start Default Directory
Escape Double Quotes in a String