Search code examples
c#listboxdoublebuffered

double buffer customer drawn list box


I have a custom draw method so I can make items in a list box different colours. The problem is that I redraw the listbox every 500ms to check if the values have changed. This makes the listbox flicker and I am not sure how to double buffer the code. Can anyone help please?

private void listBox_DrawItem(object sender, DrawItemEventArgs e)
{
    ListBox sendingListBox = (ListBox)sender;

    CustomListBoxItem item = sendingListBox.Items[e.Index] as CustomListBoxItem; // Get the current item and cast it to MyListBoxItem

    if (item != null)
    {
         e.Graphics.DrawString( // Draw the appropriate text in the ListBox
            item.Message, // The message linked to the item
            zone1ListBox.Font, // Take the font from the listbox
            new SolidBrush(item.ItemColor), // Set the color 
            0, // X pixel coordinate
            e.Index * zone1ListBox.ItemHeight // Y pixel coordinate.  Multiply the index by the ItemHeight defined in the listbox.
         );
    }
    else
    {
        // The item isn't a MyListBoxItem, do something about it
    }
}

Solution

  • If you need to enable the double buffer of the ListBox you should inherit a class from it, because the property is private and set it to true, or use the SetStyle() method and apply the WS_EX_COMPOSITED flag:

    public class DoubleBufferedListBox : ListBox {
        protected override CreateParams CreateParams {
            get {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;   // WS_EX_COMPOSITED
                return cp;
            }
        }
    
        public DoubleBufferedListBox( ) {
            this.SetStyle(ControlStyles.DoubleBuffer, true);         
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        }
    }