Windows Forms apps have a well known issue that when you have a bunch of controls on your form (not to mention any 3rd party controls), the app flickers, there is UI tearing – it's just not pretty.  The problem most seems to impact the startup of the app when everything is being loaded.

Simply setting the form and any controls to be Double Buffered doesn’t do the trick because the .DoubleBuffered property works at a control level, not the form level. 

There is a fix for this that automatically enables double-buffering at the form level and on down.  This works by setting the WS_EX_COMPOSITED flag in the Form.CreateParams.ExStyle property.  Just drop the following code into form:

protected override CreateParams CreateParams
{
    get
    {
        // Activate double buffering at the form level.  All child controls will be double buffered as well.
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;   // WS_EX_COMPOSITED
        return cp;
    }
} 


This fix works relatively well, but WS_EX_COMPOSITED flag causes a couple of side effects:

  • The Maximize, Minimize and Close buttons don’t animate on Windows XP.
  • Resizing a control-heavy form feels very laggy because everything is being double-buffered.

The trick to fix both issues, it turns out, is the same, though very hacky.  The idea is to turn off the WS_EX_COMPOSITED flag right after the form is loaded and thus turning the form-level double-buffering off. So replace the above code with the following:

int originalExStyle = -1;
bool enableFormLevelDoubleBuffering = true;
 
protected override CreateParams CreateParams
{
    get
    {
        if (originalExStyle == -1)
            originalExStyle = base.CreateParams.ExStyle;
 
        CreateParams cp = base.CreateParams;
        if (enableFormLevelDoubleBuffering)
            cp.ExStyle |= 0x02000000;   // WS_EX_COMPOSITED
        else
            cp.ExStyle = originalExStyle;
 
        return cp;
    }
} 

 

So the pieces are in place: when enableFormLevelDoubleBuffering is set to false, we’ll have to get the System.Windows.Forms.Form object to call the CreateParams method and, in doing so, reset the ExStyle flag.  But how can we get the app to call CreateParams

For reasons I don’t know, simply calling the following does the trick:

this.MaximizeBox = true;


Yes, did I mention, it was hacky?  So let’s create a method that does all the work:

private void TurnOffFormLevelDoubleBuffering()
{
    enableFormLevelDoubleBuffering = false;
    this.MaximizeBox = true;
}


And we should call this method after the form has loaded in the Shown event:

private void frmMain_Shown(object sender, EventArgs e)
{
    TurnOffFormLevelDoubleBuffering();
}

And that’s how we roll.