How to fix the flickering in User controls

后端 未结 12 1563
佛祖请我去吃肉
佛祖请我去吃肉 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条回答
  •  孤城傲影
    2020-11-22 02:42

    I combined this flicker fix and this font fix, then I had to add a bit of my own code to start a timer on paint to Invalidate the TabControl when it goes offscreen and back, etc..

    All three make this:

    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    public class TabControlEx:TabControl
    {
        [DllImport("user32.dll")]
        private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
        private const int WM_PAINT = 0x0f;
        private const int WM_SETFONT = 0x30;
        private const int WM_FONTCHANGE = 0x1d;
        private System.Drawing.Bitmap buffer;
        private Timer timer = new Timer();
        public TabControlEx()
        {
            timer.Interval = 1;
            timer.Tick += timer_Tick;
            this.SetStyle(ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
        }
        void timer_Tick(object sender, EventArgs e)
        {
            this.Invalidate();
            this.Update();
            timer.Stop();
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_PAINT) timer.Start();
            base.WndProc(ref m);
        }
        protected override void OnPaint(PaintEventArgs pevent)
        {
            this.SetStyle(ControlStyles.UserPaint, false);
            base.OnPaint(pevent);
            System.Drawing.Rectangle o = pevent.ClipRectangle;
            System.Drawing.Graphics.FromImage(buffer).Clear(System.Drawing.SystemColors.Control);
            if (o.Width > 0 && o.Height > 0)
            DrawToBitmap(buffer, new System.Drawing.Rectangle(0, 0, Width, o.Height));
            pevent.Graphics.DrawImageUnscaled(buffer, 0, 0);
            this.SetStyle(ControlStyles.UserPaint, true);
        }
    
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            buffer = new System.Drawing.Bitmap(Width, Height);
        }
        protected override void OnCreateControl()
        {
            base.OnCreateControl();
            this.OnFontChanged(EventArgs.Empty);
        }
        protected override void OnFontChanged(EventArgs e)
        {
            base.OnFontChanged(e);
            IntPtr hFont = this.Font.ToHfont();
            SendMessage(this.Handle, WM_SETFONT, hFont, (IntPtr)(-1));
            SendMessage(this.Handle, WM_FONTCHANGE, IntPtr.Zero, IntPtr.Zero);
            this.UpdateStyles();
        }
    }
    

    I'm not the creator but from what I understand the bitmap does all the bug bypassing.

    This was the only thing that definitively solved TabControl (with Icons) flicker for me.

    difference result video: vanilla tabcontrol vs tabcontrolex

    http://gfycat.com/FineGlitteringDeermouse

    ps. you will need to set HotTrack = true, because this fixes that bug too

提交回复
热议问题