How to fix the flickering in User controls

后端 未结 12 1648
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-22 02:32

In my application i am constantly moving from one control to another. I have created no. of user controls, but during navigation my controls gets flicker. it takes 1 or 2 se

12条回答
  •  闹比i
    闹比i (楼主)
    2020-11-22 02:33

    This is a real issue, and the answer Hans Passant gave is great for saving the flicker. However, there are side effects as he mentioned, and they can be ugly (UI ugly). As stated, "You can turn off the WS_CLIPCHILDREN style flag for the UC", but that only turns it off for a UC. The components on the main form still have issues.

    Example, a panel scroll bar doesn't paint, because it is technically in the child area. However the child component doesn't draw the scroll bar, so it doesn't get painted until mouse over (or another event triggers it).

    Also, animated icons (changing icons in a wait loop) doesn't work. Removing icons on a tabPage.ImageKey doesn't resize/repaint the other tabPages appropriately.

    So I was looking for a way to turn off the WS_CLIPCHILDREN on initial painting so my Form will load nicely painted, or better yet only turn it on while resizing my form with a lot of components.

    The trick is to get the application to call CreateParams with the desired WS_EX_COMPOSITED/WS_CLIPCHILDREN style. I found a hack here (https://web.archive.org/web/20161026205944/http://www.angryhacker.com/blog/archive/2010/07/21/how-to-get-rid-of-flicker-on-windows-forms-applications.aspx) and it works great. Thanks AngryHacker!

    I put the TurnOnFormLevelDoubleBuffering() call in the form ResizeBegin event and TurnOffFormLevelDoubleBuffering() call in the form ResizeEnd event (or just leave it WS_CLIPCHILDREN after it is initially painted properly.)

        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;
            }
        }
    
        public void TurnOffFormLevelDoubleBuffering()
        {
            enableFormLevelDoubleBuffering = false;
            this.MaximizeBox = true;
        }
    

提交回复
热议问题