How can I set the protected DoubleBuffered
property of the controls on a form that are suffering from flicker?
14 Answers
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);
}

- 8,414
- 4
- 39
- 69

- 246,734
- 253
- 869
- 1,219
-
Funny, I'd think that it's even more important to double-buffer when remoting, so that you avoid needlessly sending a bunch of repaints over the wire? – Robert Jeppesen Jun 11 '09 at 14:50
-
15It's exactly what you don't want. In a terminal session the GDI system can send commands (draw line here, draw circle here, fill here, etc). Double buffering is accomplished by you drawing everyting onto a bitmap and then using GDI to paint your entire form as a bitmap. Sending an uncompressed bitmap over the wire is *MUCH* slower than sending the origianl GDI commands. – Ian Boyd Jun 12 '09 at 18:50
-
Doesn't help prevent an auto-sized TextBox from flickering on resize... In fact nothing I have tried so far does. – Roman Starkov Aug 26 '09 at 08:57
-
3@Boris That's because the Windows `TEXTBOX` control [doesn't obey any](http://stackoverflow.com/questions/1955538/win32-how-to-custom-draw-an-edit-control) laws of painting. – Ian Boyd Nov 30 '12 at 18:51
-
2@romkyns, If you need a double-buffered `TextBox`, use a `RichTextBox` with `DetectUrls` set to False. If you want it to be editable, strip the formatting using the [EM_SETCHARFORMAT](http://msdn.microsoft.com/en-us/library/windows/desktop/bb774230.aspx) and [EM_SETPARAFORMAT](http://msdn.microsoft.com/en-us/library/windows/desktop/bb774276.aspx) messages (example code [is here](http://social.msdn.microsoft.com/Forums/windows/en-US/596ee31b-1eff-4ac9-a68f-b46d7c4059ae/how-do-i-set-the-richtextboxselectionfont-fontfamily-without-changing-the-style)). – alldayremix Jun 27 '13 at 22:16
-
@IanBoyd I know this is an extremely old question - but thought I'd give the a try anyway. I had the same issue with my app, so I converted the above code to VB.NET and added it into my main form class. I then added `SetDoubleBuffered(SplashScreen)` immediately before `SplashScreen.Show()` in my `DisplaySplash` `Sub`. It works! However I'm completely new to this kind of thing, and am unsure if this is the correct way to implement this? – Dec 29 '20 at 23:03
-
Hmm, so what you're saying is that `TerminalServerSession` is an exceptional case that you should probably look out for at run-time? – Gregor y Apr 22 '21 at 15:40
-
@Gregory Correct. Along with respecting the user's font family, font size, color choices, high-contrast setting, disable animation settings, allow keyboard shortcuts for those who can't use a mouse. You know: things that almost no application does anymore. – Ian Boyd Apr 22 '21 at 17:41
-
huh, I haven't used an IDE in ages, but I would have thought that stuff got shoved down into the code-folds of VS somewhere. Also, is there a benefit to setting the property vs using the same reflection technique to call `SetStyle` with the 3 flags `DoubleBuffer | UserPaint | AllPaintingInWmPaint` – Gregor y Apr 22 '21 at 23:44
Check this thread
Repeating the core of that answer, you can turn on the WS_EX_COMPOSITED style flag on the window to get both the form and all of its controls double-buffered. The style flag is available since XP. It doesn't make painting faster but the entire window is drawn in an off-screen buffer and blitted to the screen in one whack. Making it look instant to the user's eyes without visible painting artifacts. It is not entirely trouble-free, some visual styles renderers can glitch on it, particularly TabControl when its has too many tabs. YMMV.
Paste this code into your form class:
protected override CreateParams CreateParams {
get {
var cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
The big difference between this technique and Winform's double-buffering support is that Winform's version only works on one control at at time. You will still see each individual control paint itself. Which can look like a flicker effect as well, particularly if the unpainted control rectangle contrasts badly with the window's background.

- 922,412
- 146
- 1,693
- 2,536
-
-
This solution causes problems with WPF controls hosted inside an ElementHost. The control will not be drawn correctly. – PeterB Jun 21 '18 at 13:03
-
If you have a Form with a Splitter Container do NOT use WS_EX_COMPOSITED ! – Elmue Oct 26 '19 at 13:01
System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control)
.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
aProp.SetValue(ListView1, true, null);
Ian has some more information about using this on a terminal server.
public void EnableDoubleBuffering()
{
this.SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint,
true);
this.UpdateStyles();
}

- 2,169
- 1
- 15
- 12
One way is to extend the specific control you want to double buffer and set the DoubleBuffered property inside the control's ctor.
For instance:
class Foo : Panel
{
public Foo() { DoubleBuffered = true; }
}

- 9,822
- 3
- 30
- 28
Extension method to turn double buffering on or off for controls
public static class ControlExtentions
{
/// <summary>
/// Turn on or off control double buffering (Dirty hack!)
/// </summary>
/// <param name="control">Control to operate</param>
/// <param name="setting">true to turn on double buffering</param>
public static void MakeDoubleBuffered(this Control control, bool setting)
{
Type controlType = control.GetType();
PropertyInfo pi = controlType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(control, setting, null);
}
}
Usage (for example how to make DataGridView DoubleBuffered):
DataGridView _grid = new DataGridView();
// ...
_grid.MakeDoubleBuffered(true);

- 13,770
- 12
- 63
- 77
nobugz gets the credit for the method in his link, I'm just reposting. Add this override to the Form:
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
This worked best for me, on Windows 7 I was getting large black blocks appearing when I resize a control heavy form. The control now bounce instead! But it's better.
This caused me a lot of grief for two days with a third party control until I tracked it down.
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
I recently had a lot of holes (droppings) when re-sizing / redrawing a control containing several other controls.
I tried WS_EX_COMPOSITED and WM_SETREDRAW but nothing worked until I used this:
private void myPanel_SizeChanged(object sender, EventArgs e)
{
Application.DoEvents();
}
Just wanted to pass it on.

- 140
- 1
- 9
vb.net version of this fine solution....:
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or &H2000000
Return cp
End Get
End Property

- 41
- 2
Before you try double buffering, see if SuspendLayout()/ResumeLayout() solve your problem.

- 399,467
- 113
- 570
- 794
-
3Suspend/ResumeLayout doesn't solve the problem of flicker when painting. – Ian Boyd Oct 29 '09 at 17:20
You can also inherit the controls into your own classes, and set the property in there. This method is also nice if you tend to be doing a lot of set up that is the same on all of the controls.

- 9,695
- 6
- 32
- 43
I created a static method that accepts a Control
and sets the DoubleBuffered
property to true
to each and every children recursively.
public static void CascadingDoubleBuffer(Control c)
{
var p = c.GetType().GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
p?.SetValue(c, true, null);
foreach (Control cc in c.Controls) CascadingDoubleBuffer(cc);
}
I created a custom calendar using DataGridView
that refreshes everytime the user interacts with it, this method removes the migraine-inducing flicker.

- 36
- 3
I have found that simply setting the DoubleBuffered setting on the form automatically sets all the properties listed here.

- 50,140
- 28
- 121
- 140

- 37,275
- 36
- 106
- 124
FWIW
building on the work of those who've come before me:
Dummy's Solution, Ian Boyd's Solution, Amo's Solution
here is a version that sets double buffering via SetStyle
in PowerShell using reflection
function Set-DoubleBuffered{
<#
.SYNOPSIS
Turns on double buffering for a [System.Windows.Forms.Control] object
.DESCRIPTION
Uses the Non-Public method 'SetStyle' on the control to set the three
style flags recomend for double buffering:
UserPaint
AllPaintingInWmPaint
DoubleBuffer
.INPUTS
[System.Windows.Forms.Control]
.OUTPUTS
None
.COMPONENT
System.Windows.Forms.Control
.FUNCTIONALITY
Set Flag, DoubleBuffering, Graphics
.ROLE
WinForms Developer
.NOTES
Throws an exception when trying to double buffer a control on a terminal
server session becuase doing so will cause lots of data to be sent across
the line
.EXAMPLE
#A simple WinForm that uses double buffering to reduce flicker
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Pen = [System.Drawing.Pen]::new([System.Drawing.Color]::FromArgb(0xff000000),3)
$Form = New-Object System.Windows.Forms.Form
Set-DoubleBuffered $Form
$Form.Add_Paint({
param(
[object]$sender,
[System.Windows.Forms.PaintEventArgs]$e
)
[System.Windows.Forms.Form]$f = $sender
$g = $e.Graphics
$g.SmoothingMode = 'AntiAlias'
$g.DrawLine($Pen,0,0,$f.Width/2,$f.Height/2)
})
$Form.ShowDialog()
.LINK
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.setstyle?view=net-5.0
.LINK
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.controlstyles?view=net-5.0
#>
param(
[parameter(mandatory=$true,ValueFromPipeline=$true)]
[ValidateScript({$_ -is [System.Windows.Forms.Control]})]
#The WinForms control to set to double buffered
$Control,
[switch]
#Override double buffering on a terminal server session(not recomended)
$Force
)
begin{try{
if([System.Windows.Forms.SystemInformation]::TerminalServerSession -and !$Force){
throw 'Double buffering not set on terminal server session.'
}
$SetStyle = ([System.Windows.Forms.Control]).GetMethod('SetStyle',
[System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance
)
$UpdateStyles = ([System.Windows.Forms.Control]).GetMethod('UpdateStyles',
[System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance
)
}catch {$PSCmdlet.ThrowTerminatingError($PSItem)}
}process{try{
$SetStyle.Invoke($Control,@(
([System.Windows.Forms.ControlStyles]::UserPaint -bor
[System.Windows.Forms.ControlStyles]::AllPaintingInWmPaint -bor
[System.Windows.Forms.ControlStyles]::DoubleBuffer
),
$true
))
$UpdateStyles.Invoke($Control,@())
}catch {$PSCmdlet.ThrowTerminatingError($PSItem)}}
}

- 1,762
- 15
- 22