Список нарисованный владельцем не рисует ранее выбранный элемент
Я хочу увеличить высоту элементов в списке - в основном, чтобы добавить их. Кроме этого, я не хочу изменять поведение списка по умолчанию. Я следовал примеру MSDN для создания списков, нарисованных владельцем, но у меня проблема. В списке по умолчанию элементы отображаются черным, а выбранный элемент - белым с синей подсветкой. Для реализации той же функциональности я использовал следующий код в обработчике события DrawItem:
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();
}
Кажется, это работает нормально, кроме случаев, когда я нажимаю на список. Выбранный элемент отображается белым текстом на синем фоне, но ранее выбранный элемент остается белым. Кажется, что элемент, который я выбрал, перерисован, но ранее выбранный элемент - нет. Если я перехожу к другому элементу управления, список перерисовывается нормально. Что мне не хватает?
2 ответа
Чтобы добавить отступ к списку, просто установите.ItemHeight списка на некоторую высоту.
В противном случае, если вы хотите сделать рисование владельцем, вместо того, чтобы выбирать цвет вручную, используйте e.ForeColor. Как это:
Brush b = new SolidBrush(e.ForeColor);
Обратите внимание, что в этом случае вам придется рисовать фон и для выбранного элемента. Проверка состояния элемента списка может быть выполнена следующим образом:
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));
Ответ: ListBox.SelectedIndex
очень иррационально (как сказал Ганс), но e.ForeColor
достаточно правильно. Используйте это вместо этого.
Замените свой код: e.Index == ((ListBox)sender).SelectedIndex
с e.ForeColor == SystemColors.HighlightText
Вспомогательные данные:
Добавьте эту строку в начало listBox1_DrawItem
:
Console.WriteLine("e.Index=" + e.Index + " SelectedIndex=" +
listBox1.SelectedIndex + " ForeColor=" + e.ForeColor);
Это производит вывод как это ( // аннотированный)
// 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)
Так что в основном... ListBox может рисовать больше, чем мы хотим, но в итоге вы получите правильные цвета во время последнего рисования.
Я также рекомендую DoubleBuffering.