0

After I minimize the form, and pop it back up, the listBox (which is OwnerDrawned so I can customize the colors and behavior to my likings) starts to flicker when I hover over the items.

How to fix this ?

I've tried several solutions by now, like https://www.codeproject.com/Answers/473893/FlickeringplusinplusaplusWindowsplusFormplusapplic and https://www.codeproject.com/Answers/728560/Remove-flickering-due-to-TableLayoutPanel-Panel-2 but also, https://stackoverflow.com/a/3718648/10012792 but none seem to fix the flickering AFTER I minimized the app and pop it back up.

    {
        private int _MouseIndex = -1;

        public Form1()
        {
            InitializeComponent();

            ResizeRedraw = true;
            DoubleBuffered = true;
        }
        public static void SetDoubleBuffered(System.Windows.Forms.Control c)
        {
            if (System.Windows.Forms.SystemInformation.TerminalServerSession)
                return;
            System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            aProp.SetValue(c, true, null);
        }
        protected override CreateParams CreateParams
        {
            get
            {
                // Activate double buffering at the form level.  All child controls will be double buffered as well.
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED
                return cp;
            }
        }
        {
            DoubleBuffered = true; 

            if (e.Index < 0) return; 

            //e.DrawBackground();
            Color borderColor = Color.FromArgb(255, 42, 42, 42); 

            bool isItemSelected = ((e.State & DrawItemState.Selected) == DrawItemState.Selected);
            using (SolidBrush bgBrush = new SolidBrush(isItemSelected ? Color.FromArgb(255, 52, 52, 52) : Color.FromArgb(255, 29, 29, 29)))
            using (SolidBrush overlay = new SolidBrush(isItemSelected ? Color.FromArgb(255, 42, 42, 42) : Color.FromArgb(255, 42, 42, 42)))
            using (SolidBrush itemBrush = isItemSelected ? new SolidBrush(Color.FromArgb(255, 68, 201, 94)) : new SolidBrush(Color.FromArgb(255, 243, 243, 243)))
            {
                string itemText = listBoxTracks.GetItemText(listBoxTracks.Items[e.Index]); 

                e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; 
                SizeF size = e.Graphics.MeasureString(listBoxTracks.ToString(), e.Font); 
                e.Graphics.FillRectangle(bgBrush, e.Bounds); 
                e.Graphics.DrawRectangle(new Pen(borderColor), e.Bounds); 
                e.Graphics.DrawString(itemText, e.Font, itemBrush, e.Bounds.Left + (e.Bounds.Width / 22 - size.Width / 44), e.Bounds.Top + (e.Bounds.Height / 2 - size.Height / 2)); 

                if (e.Index == _MouseIndex)
                {
                    e.Graphics.FillRectangle(overlay, e.Bounds);
                    e.Graphics.DrawString(itemText, e.Font, itemBrush, e.Bounds.Left + (e.Bounds.Width / 22 - size.Width / 44), e.Bounds.Top + (e.Bounds.Height / 2 - size.Height / 2));
                }

            }
        }
        {
            int index = listBoxTracks.IndexFromPoint(e.Location);
            if (index != _MouseIndex)
            {
                _MouseIndex = index;
                listBoxTracks.Invalidate();
            }
        }
        {
            if (_MouseIndex > -1)
            {
                _MouseIndex = -1;
                listBoxTracks.Invalidate();
            }
        }

I expect the output to be non-flickery, since the methods I used should prevent this.

I had a hard time to register it to show since internal recording using Camtasia, Nvidia's overlay nor my iPhone SE could show it afterwards in the recording. Mirillis Action! however did on 144fps, see: https://i.stack.imgur.com/Onq8C.jpg

Sourcecode here: https://mega.nz/#!kIJlAQ5S!l9hTXxYE0lcg4iNH3TUcIly3TaDCrtWlPs1xKttS7ws

Bas Curtiz
  • 73
  • 8
  • We need to know where those last 2 snippets are. They are causing it to redraw so when, where and how often is not trivial – Ňɏssa Pøngjǣrdenlarp May 26 '19 at 14:24
  • @Nat Pongjardenlarp They are right below the ListBox DrawItem in the code. See: https://imgur.com/VpKKlXF – Bas Curtiz May 26 '19 at 14:30
  • Remove `DoubleBuffered` from anywhere (especially the `DrawItem` method), `SetDoubleBuffered` (completely useless if not harmful) and `ResizeRedraw`. Keep just the Form's `CreateParams` override. If you want to keep your code as it is, you'll have to recreate the Form's handle when its `WindowState` is restored, if the previous state was `FormWindowState.Minimized`. Call `this.RecreateHandle();` when these conditions are met (it will call `CreateParams` again). – Jimi May 26 '19 at 15:38
  • Like this? ```public System.Windows.Forms.FormWindowState WindowState { get; set; }``` ```private void Form1_Shown(object sender, EventArgs e) { this.WindowState = FormWindowState.Maximized; { if (WindowState = FormWindowState.Minimized) { this.RecreateHandle(); } } } ``` – Bas Curtiz May 26 '19 at 17:05
  • More like this: `FormWindowState previousState = FormWindowState.Normal; private void Form1_Resize(object sender, EventArgs e) { if (this.WindowState == FormWindowState.Minimized) { previousState = FormWindowState.Minimized; } else if (this.WindowState == FormWindowState.Normal) { if (previousState == FormWindowState.Minimized) { this.RecreateHandle(); } previousState = FormWindowState.Normal; } }`. Subscribe to the event, of course. – Jimi May 26 '19 at 17:17
  • @Jimi You're the best. Works like a charm! Can you insert that code to answer the question, so people can upvote it? – Bas Curtiz May 26 '19 at 18:19
  • And now it doesn't work, when I implement it back in my existing project argh! I'm using a custom made window shadow drop: https://github.com/NetDimension/WinForm-ModernUI + added a gradient background: http://www.daveoncsharp.com/2009/09/how-to-paint-a-gradient-background-for-your-forms/ and stripped the whole GUI in fact incl. min, max, close buttons, and created my own. – Bas Curtiz May 26 '19 at 19:23
  • ```System.InvalidOperationException: "Invoke or BeginInvoke cannot be invoked on a control until the window link is created."``` on ```this.RecreateHandle();``` when I minimize and pop it back up. When I rename ```public partial class frmMain : ModernUIForm``` to ```public partial class frmMain : Form``` and disable its parameters in Designer.cs ```this.ActiveBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(62)))), ((int)(((byte)(62)))), ((int)(((byte)(62)))));``` and ```this.BorderWidth = 0;``` it works again. But then it shows the default native topbar from Windows again. – Bas Curtiz May 26 '19 at 19:56
  • I can hide it using ```FormBorderStyle = FormBorderStyle.None;``` after ```InitializeComponent();``` but then I get the message: ```System.ComponentModel.Win32Exception: "Error creating the window link."``` on ```RecreateHandle();``` – Bas Curtiz May 26 '19 at 20:19
  • This always happens when you have you a thread that updates UI components. Check whether the Control you're about to update/reference in any way has a handle (`[Control].IsHandleCreated == true`). – Jimi May 26 '19 at 21:02
  • I've searched for it, but also on ```[Control]``` or ```HandleCreated``` but it's simply not present. I've now implemented the ```NetDimension WinForm-ModernUI``` to your working solution and the error occurs, after minimizing/popping up. Perhaps you want to take a quick look if u see something that troubles you? Sourcecode: https://mega.nz/#!pZZTCaza!dloH_TJWrNaz4hOKkXBS2zGv_3JD0vc8kCNsWfjqEAw Example: https://imgur.com/a/tM93Wc9 – Bas Curtiz May 26 '19 at 22:36
  • And the working solution, but with ```Border set to none``` source: https://mega.nz/#!QNZBGayA!nHPJmjuWsNMS_nlIuJ7R-RfWAA2VlNrW1TKzYt-fwOg – Bas Curtiz May 26 '19 at 22:50
  • I found a lot of ```IsHandleCreated``` in the source of ```NetDimension Winform-ModernUI``` here: https://github.com/NetDimension/WinForm-ModernUI/blob/master/NetDimension.WinForm/ModernUIForm.cs#L282 – Bas Curtiz May 27 '19 at 08:55

0 Answers0