0

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
    }
}
Omar
  • 16,329
  • 10
  • 48
  • 66
user1696698
  • 219
  • 3
  • 12
  • The native ListBox control does not support double-buffering. Use a ListView instead with View = List. And this code: http://stackoverflow.com/a/8378761/17034 – Hans Passant Nov 02 '12 at 18:38

1 Answers1

4

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);
    }
}
Elmue
  • 7,602
  • 3
  • 47
  • 57
Omar
  • 16,329
  • 10
  • 48
  • 66
  • thanks for the reply. the list box is a windows control so i'm not sure how i can redefine it as a doubleBufferedListBox? – user1696698 Nov 02 '12 at 18:01
  • Do you mean that you are setting it from the designer window? – Omar Nov 02 '12 at 18:05
  • yes i set the control from the designer window and simply place it on the form, so it is defined as a ListBox and I am don't know how to call your code with the custom list box. Is there no a way to make the graphics object double buffered in my code? – user1696698 Nov 02 '12 at 18:17
  • 1
    If you want to use the current listbox in the windows designer, you can open Form.Designer.cs find where is declared the listbox and make it `private DoubleBufferedListBox listBoxName;` and then find where it is initialized and initialize it as `listBoxName = new DoubleBufferedListBox()`. Else if you want to add a new DoubleBufferedListBox from the toolbox compile the code one time and then you will find it. – Omar Nov 02 '12 at 18:38
  • If anyone is getting error that `ControlStyles.DoubleBuffered` not found then use `ControlStyles.DoubleBuffer` – striker_axel Sep 04 '15 at 09:02