2

I have a custom control containing a mixture of custom and standard controls. When the control is made larger, I'm getting background coloured rectangles where the child control will be painted, before the paint of the child control completes. It's the same for both my custom controls and the standard ones.

I thought that suspend layout was the way to avoid this, but it isn't working for me.

I suspend layout for the container and all its controls while the resizing takes place.

Do I need to override the paint method for the child controls? Surely that would mean new custom controls to replace all the standard ones, or do I need to override the paint method for the container?

bobinski
  • 99
  • 1
  • 11
  • Are you seeing this in the designer, or at runtime? At runtime something like what you describe isn't normal - it may be the result of something you're doing in your container control. Can you post the code, or better yet a simple working (compilable) sample that shows the problem? – MusiGenesis Mar 06 '11 at 12:42
  • I'm getting the effect at runtime only. – bobinski Mar 06 '11 at 12:54
  • Yet again I pressed enter to get a newline and sent an incomplete message by mistake. – bobinski Mar 06 '11 at 12:56
  • I'll look through my container code and create a sample. Not sure when though. – bobinski Mar 06 '11 at 12:57
  • CORRECTION, It's different - less obvious, probably different timing, but there at design time too. – bobinski Mar 06 '11 at 13:02
  • The effect is noticeable at design time with a standard panel containing a standard button so long as the form's background differs from the panel's and you resize quickly. The effect I'm getting is more noticeable as I have more things happening which slow down the painting. – bobinski Mar 06 '11 at 13:22
  • Are your child controls set to be transparent? – Cody Gray - on strike Mar 06 '11 at 13:33
  • No, my controls are not transparent. I don't think it's relevant. See the answer from @Sisyphus and the comments below. – bobinski Mar 06 '11 at 19:47

1 Answers1

0

EDITED to correct information and reference

One approach is to double buffer. People often set this style and assume it is working but you may not in fact get double buffering for various reasons. But true double buffering can have some negative consequences too.

The following solution provide by Hans Passant will typically fix this sort of problem without causing some of the side effects of double buffering.

label backgrond flicking on a WinForms user control has background image enabled

By removing the WS_CLIPCHILDREN attribute the spaces the controls are supposed to occupy will be filled with background first which can reduce the artifacts you see waiting for the controls to be drawn

Add the following code to your custom control:

protected override CreateParams CreateParams
    {
        get
        {
            CreateParams parms = base.CreateParams;
            parms.Style &= ~0x02000000;  // Turn off WS_CLIPCHILDREN
            return parms;
        }
    }
Community
  • 1
  • 1
Sisyphus
  • 4,181
  • 1
  • 22
  • 15
  • I'm getting the form's background showing in the space where the control will expand to. If my panel and form had the same background colour it would not be noticeable. However, that's not what I want. – bobinski Mar 06 '11 at 13:31
  • I could not reprooduce the effect using your sample code but have you tried turning double buffering on the form to see if it even helps? Enable WS_EX_COMPOSITED to double buffer the form. – Sisyphus Mar 06 '11 at 13:53
  • Yes, I've tried `this->SetStyle(ControlStyles::UserPaint | ControlStyles::AllPaintingInWmPaint | ControlStyles::OptimizedDoubleBuffer, true);` – bobinski Mar 06 '11 at 15:26
  • I now get the border drawn all over the place and changing the border in the OnPaint event just loops! – bobinski Mar 06 '11 at 15:28
  • This is an "attribution required" site, check the cc-wiki link at the bottom of the page. When your post contains content that is an *exact* match then you have to post a link to the original as well as its author. Please take care of it. http://stackoverflow.com/questions/2454111/label-backgrond-flicking-on-a-winforms-user-control-has-background-image-enabled/2454515#2454515 – Hans Passant Mar 06 '11 at 15:36
  • Setting the ControlStyles::OptimizedDoubleBuffer is NOT the same as enabling the WS_EX_COMPOSITED on the form. Enabling WS_EX_COMPOSITED on the form will force all the child controls in the entire hierarchy to be double buffered. It often fixes many kinds of flickering but is heavy handed and can also introduce other bugs. – Sisyphus Mar 06 '11 at 16:18
  • Well, it appears that I need both. With just WS_EX_COMPOSITED enabled, the border flickers on and off. With OptimizedDoubleBuffer set on the container I get visible gaps. With both set I'm very close to what I want. No flicker, no visible gaps. My controls are working as I want, but the standard button leaves residue briefly, when it's moved down. Ah, it's only a problem when there's a lot of debug code! The release version is absolutely fine. AT LAST!!!!!!!!!!! – bobinski Mar 06 '11 at 19:31
  • Here's the code I added: `public: virtual property System::Windows::Forms::CreateParams^ CreateParams { System::Windows::Forms::CreateParams^ get() override { System::Windows::Forms::CreateParams^ cp = __super::CreateParams; cp->Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN return cp; } } ` – bobinski Mar 06 '11 at 19:37