How to fix nested winform control flicker issues

2020-06-03 02:44发布

问题:

I am currently working on a program that uses a fairly complex structure of nested winform controls which changes dynamically as a user makes certain selections. To go into more detail about the specific layout of the controls would be to extensive for this question.

When ever a selection is made, a lot of updates are made to the underlying model which is controlled by the user controls. This then results in series of corresponding changes in the size/position/visibility of the displayed controls. All of these changes results in a painfully intense flickering of controls on the screen. I need to somehow fix this so that everytime the user makes a selection the screen is basically frozen until all of the control updates have completed.

I have attempted to use the Control.SuspendLayout/Control.ResumeLayout methods in many different places and ways and I can not eliminate the crazy flickering. I thought that suspending layout on the root control during the changes would fix the problem but it appears that this SuspendLayout doesn't help when child controls are changed.

Do I need to use some other approach rather than SuspendLayout? Is there a way I can debug SuspendLayout to see why it doesn't appear to be cascading to all of the child controls?

回答1:

Suspend/ResumeLayout isn't your problem here. That only suspends automatic layout, the kind that is triggered by the Anchor and Dock properties. Double-buffering can't fix your problem either, that only suppresses flicker in each individual control. Your real problem is that you are updating too many controls at the same time, each will take its turn to paint itself and that takes time.

What you need is a different kind of double-buffering, compositing. Check out if the solution in this thread solves your problem.



回答2:

In addition to @tommieb75's suggestion for double buffering, you can try and see if your root level controls have BeginUpdate/EndUpdate method pairs. These should help repress the repaints in between the calls.



回答3:

If you are using WinForms 2+ then you can just set the 'Control.DoubleBuffer' property on the control to true (in the designer even).

With framework 2, setting DoubleBuffered sets the 3 flags : OptimizedDoubleBuffer, AllPaintingInWmPaint, and and another that I forgot, 'UserPaint' perhaps.

Also, do look at the BeginUpdate/EndUpdate as mentioned by @yetapb.



回答4:

Use the SetControlStyles in the user Control, the flag is OptimizedDoubleBuffer which will prevent the flickering.