3

I have some questions regarding flickering and the general flow of UI updates when multiple objects are involved.

Background: We use a C# assembly inside a Progress ABL application to drive the UI. Additionally we use Infragistics controls, as they can easily be styled. We have a kind of self made MDI. (tab) panels contain multiple user controls which are used as "Forms". (Note: Real forms could not be used, because a non-toplevel form has problems handling mouse clicks correctly) The tabs are realized by an Infragistics UltraDockManager.

On such an UserControl "form" a Progress .Net Control is placed which embeds real Progress Frames. So we could re-use existing Progress Forms instead of rebuilding them in .NET from scratch. To make things worse we use a tiled backgroundimage on the (tab) panels.

Now we have the problem that the contents of the panel (derived from Infragistics.Win.Misc.UltraPanel) are flickering heavily. (Especially when the main application is resized) Some controls (especially the Progress controls) are deleted and redrawn.

I could get rid of the flickering by using WS_CLIPCHILDREN and WS_EX_COMPOSITED (as mentioned by Hans Passant in How to fix the flickering in User controls ) in the panel and the UserControl. But the application was noticeably slower than before, so I had to removed the code again.

I tried setting the Styles of the panel and the UserControl, with absolutely no effect.

this.SetStyle(ControlStyles.AllPaintingInWmPaint |
              ControlStyles.UserPaint |
              ControlStyles.OptimizedDoubleBuffer |
              ControlStyles.ResizeRedraw, true);

Trying to ignore WM_ERASEBKGND in the panel and the UserControl seems not to have an effect either.

protected override void WndProc(ref Message m)
{
    if (m.Msg != WM_ERASEBKGND)
    {
        base.WndProc(ref m);
    }
}

What would be the correct way to handle the redrawing of all those objects to reduce the flickering?

I thought about using SendMessage and WM_SETREDRAW. But I am not sure where to put it in this scenario and whether it would really help or not.

When the application is resized each UserControl seems to be repainted, regardless of its visibility. (Could be scrolled half way out of view) Why isn't there some kind of clipping going on? The panel should know that some areas don't need to be refreshed or am I mistaken?

I would appreciate any suggestion.

Community
  • 1
  • 1
JGR
  • 83
  • 1
  • 9

3 Answers3

3

We finally managed to get rid of the flickering. There were two factors which caused the problem:

  1. Use of Color:Transparent
  2. Use of the AutoScroll feature of the panels

We removed the transparent color and disabled the AutoScroll during resize.

JGR
  • 83
  • 1
  • 9
2

try using this in the program

It may not give the speed in between the redraw events

but it will certainly will look graceful as redrawn activity will take place after all the painting is done

you just need to add it into your main form.

protected override System.Windows.Forms.CreateParams CreateParams
        {
            get
            {
                System.Windows.Forms.CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        } 
Taj
  • 1,718
  • 1
  • 12
  • 16
  • Hi, thanks for the hint, but that's WS_EX_COMPOSITED. I already tried it. (See post above) It works, but the application is terribly slow afterwards, so I removed the code again. I hope there might be another way around. Posts in other forums also state that there might be graphical glitches when using WS_EX_COMPOSITED. – JGR May 28 '13 at 11:49
0

have a look at this and this

They are about calling SuspendLayout on Resize

Community
  • 1
  • 1
Exceptyon
  • 1,584
  • 16
  • 23
  • Hm, I tried Suspend and ResumeLayout in the OnPaint method of the panel. No joy. Is that the correct place? – JGR May 28 '13 at 12:28
  • probably not if it did not work... I'm sorry :( ...I'm following this, please post if you find a viable solution – Exceptyon May 28 '13 at 15:45