How to double buffer .NET controls on a form?

后端 未结 12 1757
旧巷少年郎
旧巷少年郎 2020-11-22 16:21

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

相关标签:
12条回答
  • 2020-11-22 16:51

    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.

    0 讨论(0)
  • 2020-11-22 16:51

    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; }
    }
    
    0 讨论(0)
  • 2020-11-22 16:51

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

    0 讨论(0)
  • 2020-11-22 16:58

    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); 
    }
    
    0 讨论(0)
  • 2020-11-22 16:58
    public void EnableDoubleBuffering()
    {
       this.SetStyle(ControlStyles.DoubleBuffer | 
          ControlStyles.UserPaint | 
          ControlStyles.AllPaintingInWmPaint,
          true);
       this.UpdateStyles();
    }
    
    0 讨论(0)
  • 2020-11-22 16:58

    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.

    0 讨论(0)
提交回复
热议问题