views:

5009

answers:

10

How can i set the protected DoubleBuffered property of the controls on a form that are suffering from flicker?

+6  A: 
public void EnableDoubleBuffering()
{
   this.SetStyle(ControlStyles.DoubleBuffer | 
      ControlStyles.UserPaint | 
      ControlStyles.AllPaintingInWmPaint,
      true);
   this.UpdateStyles();
}
Arno
+9  A: 
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.

dummy
This does the trick. i made it a generic helper function and posted it here.
Ian Boyd
It's not really for *on* a terminal server, since none of my customers run the software from a remote desktop session. But you should pay your developer taxes, and i didn't want to put out code that didn't already include the taxes.
Ian Boyd
+1  A: 

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.

MagicKat
+3  A: 

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; }
}
Jeff Hubbard
I'm working with an owner drawn ListView in a derived class. This solved the problem perfectly!
Brad Bruce
+4  A: 

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

Joel Coehoorn
Suspend/ResumeLayout doesn't solve the problem of flicker when painting.
Ian Boyd
+14  A: 

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); 
}
Ian Boyd
This code solved my problem without any modification. Thanks!
Mykroft
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
It'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
Doesn't help prevent an auto-sized TextBox from flickering on resize... In fact nothing I have tried so far does.
romkyns
A: 

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

However; I have found the double buffering provided by winforms to be less than great. This little gem of a code snippet really makes a difference, seriously try it. I spent a long time looking for a solution that worked and finally found that :-)

kronoz
The link is dead...
triton
yeah I know... I've lost that code and haven't been able to find it anywhere else on t'internet... sorry!
kronoz
+2  A: 

Check this thread

Hans Passant
Wow...talk about night and day; huge difference for me using this method.
Lurker Indeed
404-ED .
borisCallens
Typical MSFT lossage. Link updated.
Hans Passant
A: 

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.

Chris S
A: 

Just cut and pasted this and it worked great for one my custom controls which is movable, doesnt flicker at all. But I have a second control which has a gridview and including this code makes it not displcay correctly. ie most lines in grid not drawn, and text/looks almost like is low res?! Any ideas out there way worked great for one and not the other...

protected override CreateParams CreateParams
{    
  get    
    {        
      CreateParams cp = base.CreateParams;        
      cp.ExStyle |= 0x02000000;        
      return cp;    
    }
}
supermankelly