I want to increase the height of the items in a listbox - to pad them internally, basically. Other than that, I don't want to change the default listbox behavior. I have followed the MSDN example for doing owner drawn list items, but I have a problem. The default listbox draws the items in black and the selected item in white with a blue highlight. To accomplish this same functionality I used the following code in the DrawItem event handler:
private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
Brush b = (e.Index == ((ListBox)sender).SelectedIndex ? Brushes.White : Brushes.Black);
e.DrawBackground();
e.Graphics.DrawString(listBox1.Items[e.Index].ToString(), e.Font, b, new Rectangle(new Point(e.Bounds.X, e.Bounds.Y + 2), e.Bounds.Size));
e.DrawFocusRectangle();
}
This seems to work fine except when I click around the list. The selected item does show as white text on a blue background, but the previously selected item remains white. It seems like the item I select is redrawn but the previously selected item is not. If I move to another control, the listbox redraws fine. What am I missing?
To add padding to list box, just set .ItemHeight of list box to some height.
Otherwise, if you want to do owner draw, instead of selecting color manually, use e.ForeColor. Like this:
Brush b = new SolidBrush(e.ForeColor);
Note, that in such case you would have to paint background for selected item too. Checking state of list box item could be performed like this:
e.Graphics.FillRectangle((e.State & DrawItemState.Selected) != 0 ? SystemBrushes.Highlight : SystemBrushes.Window, new Rectangle(new Point(e.Bounds.X, e.Bounds.Y + 2), e.Bounds.Size));
Answer: ListBox.SelectedIndex is very irrational (like Hans said), but e.ForeColor is correct enough. Use that instead.
Replace your code: e.Index == ((ListBox)sender).SelectedIndex
with e.ForeColor == SystemColors.HighlightText
Supporting Data:
Add this line to the top of listBox1_DrawItem:
Console.WriteLine("e.Index=" + e.Index + " SelectedIndex=" +
listBox1.SelectedIndex + " ForeColor=" + e.ForeColor);
It produces output like this ( // annotated )
// Added 4 items to listbox
e.Index=0 SelectedIndex=-1 ForeColor=Color [WindowText]
e.Index=1 SelectedIndex=-1 ForeColor=Color [WindowText]
e.Index=2 SelectedIndex=-1 ForeColor=Color [WindowText]
e.Index=3 SelectedIndex=-1 ForeColor=Color [WindowText]
// MouseDown on item 0
e.Index=0 SelectedIndex=-1 ForeColor=Color [WindowText]
e.Index=0 SelectedIndex=0 ForeColor=Color [HighlightText]
e.Index=0 SelectedIndex=0 ForeColor=Color [HighlightText]
e.Index=0 SelectedIndex=0 ForeColor=Color [HighlightText]
e.Index=0 SelectedIndex=0 ForeColor=Color [HighlightText]
e.Index=0 SelectedIndex=0 ForeColor=Color [HighlightText]
e.Index=1 SelectedIndex=0 ForeColor=Color [WindowText]
e.Index=2 SelectedIndex=0 ForeColor=Color [WindowText]
e.Index=3 SelectedIndex=0 ForeColor=Color [WindowText]
e.Index=0 SelectedIndex=0 ForeColor=Color [HighlightText]
// MouseUp on item 0 (no DrawItem events)
// MouseDown for item 1
e.Index=0 SelectedIndex=0 ForeColor=Color [HighlightText]
e.Index=0 SelectedIndex=0 ForeColor=Color [WindowText]
e.Index=1 SelectedIndex=1 ForeColor=Color [HighlightText]
e.Index=1 SelectedIndex=1 ForeColor=Color [HighlightText]
// MouseUp for item 1 (no DrawItem events)
// MouseDown for item 2
e.Index=1 SelectedIndex=1 ForeColor=Color [HighlightText]
e.Index=1 SelectedIndex=1 ForeColor=Color [WindowText]
e.Index=2 SelectedIndex=2 ForeColor=Color [HighlightText]
e.Index=2 SelectedIndex=2 ForeColor=Color [HighlightText]
// Drag to item 3
e.Index=2 SelectedIndex=2 ForeColor=Color [HighlightText]
e.Index=2 SelectedIndex=2 ForeColor=Color [WindowText]
e.Index=3 SelectedIndex=3 ForeColor=Color [HighlightText]
e.Index=3 SelectedIndex=3 ForeColor=Color [HighlightText]
// MouseUp over item 3 (no DrawItem events)
So basically... ListBox maybe draws more than we want, but you end up getting the right colors during the last draws.
I also recommend DoubleBuffering.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With