ListBox не правильно перерисовывается

Здравствуйте. Написал вот такой код:


        private void LbChannelList_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.Graphics.FillRectangle(lbChannelList.SelectedIndex == e.Index ? Brushes.Blue : Brushes.White, e.Bounds);
            e.Graphics.DrawString(lbChannelList.Items[e.Index].ToString() +  " | " +  watchArr[e.Index].copiesCount.ToString(),
                lbChannelList.Font, lbChannelList.SelectedIndex == e.Index ? Brushes.White : Brushes.Black, 
                new PointF(e.Bounds.X, e.Bounds.Y));
        }

Выделенный пункт ListBox должен закрашиваться синим, а остальные белым. Но вместо этого синим закрашиваются все пункты, по которым я кликнул или водил мышью с зажатой кнопкой.

Всё, дошло. Надо вот как:

        private void LbChannelList_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.Graphics.FillRectangle((e.State & DrawItemState.Selected) == DrawItemState.Selected ? Brushes.Blue : Brushes.White, e.Bounds);
            e.Graphics.DrawString(lbChannelList.Items[e.Index].ToString() +
                " | " + watchArr[e.Index].copiesCount.ToString(),
                lbChannelList.Font, (e.State & DrawItemState.Selected) == DrawItemState.Selected ? Brushes.White : Brushes.Black,
                new PointF(e.Bounds.X, e.Bounds.Y));
        }

Но лучше так:

        private void LbChannelList_DrawItem(object sender, DrawItemEventArgs e)
        {
            bool isSelected = (e.State & DrawItemState.Selected) == DrawItemState.Selected;
            e.Graphics.FillRectangle(isSelected ? Brushes.Blue : Brushes.White, e.Bounds);
            e.Graphics.DrawString(lbChannelList.Items[e.Index].ToString() + " | " + watchArr[e.Index].copiesCount.ToString(),
                lbChannelList.Font, isSelected ? Brushes.White : Brushes.Black,
                new PointF(e.Bounds.X, e.Bounds.Y));
        }

Он опять глючит

        private void lbPlaylist_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.Graphics.FillRectangle(Brushes.Black, e.Bounds);
            if (e.Index >= 0)
            {
                bool isSelected = (e.State & DrawItemState.Selected) == DrawItemState.Selected;
                Brush brush = Brushes.Lime;
                string t = Path.GetFileName(lbPlaylist.Items[e.Index].ToString());
                e.Graphics.DrawString(t, lbPlaylist.Font, brush, new PointF(0.0f, e.Bounds.Y));
                if (isSelected)
                {
                    e.Graphics.DrawRectangle(Pens.White, e.Bounds);
                }
            }
        }

что не так?

Фоновый цвет лучше поставить заранее

lbPlaylist.BackColor = Color.Black;

Код отрисовки:

e.DrawBackground();
            if (e.Index >= 0)
            {
                bool isSelected = (e.State & DrawItemState.Selected) == DrawItemState.Selected;
                Brush brush = Brushes.Lime;
                string t = lbPlaylist.Items[e.Index].ToString();
                e.Graphics.DrawString(t, lbPlaylist.Font, brush, new PointF(0.0f, e.Bounds.Y));
                if (isSelected)
                {
                    var bnd = e.Bounds;
                    bnd.Inflate(0, -1);**
                    e.Graphics.DrawRectangle(Pens.White, bnd);
                }
            }

можно просто добавить

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            listBox1.Refresh();
        }

И само заработает.
А в другом проекте работает и без этого. Обёртки это такой рандом :man_shrugging:

Я вроде так писал уже, но не помогало. Хотя, может и не писал.

ключевой момент был в этом:

var bnd = e.Bounds;
                    bnd.Inflate(0, -1);**
                    e.Graphics.DrawRectangle(Pens.White, bnd);

Чтобы чуть чуть уменьшить прямоугольник. А перерисовывать это костыль который просто приводит к падению производительности.

Попробую. Но тогда уж лучше ширину уменьшать, чем высоту.

Ну поиграйтесь с нужным размером. По хорошему надо наверное исходники e.DrawFocusRectangle() посмотреть как они там делают.

в комьюнити версии исходники не показывают, вроде :thinking:

Исходник дотнета

Вот также уменьшают размер прямоугольника.

private static void DrawFocusRectangle(Graphics graphics, Rectangle rectangle, Color color, bool highContrast) {
            if (graphics == null) {
                throw new ArgumentNullException("graphics");
            }
            rectangle.Width--;
            rectangle.Height--;
            graphics.DrawRectangle(GetFocusPen(color,
                // we want the corner to be penned
                // see GetFocusPen for more explanation
                (rectangle.X + rectangle.Y) % 2 == 1, 
                highContrast),
                    rectangle);
        }

кстати, а вообще как его уменьшение поможет перерисоваться соседнему элементу-то? :thinking:
Проблема же в том, что предыдущий активный элемент остаётся отрисованным так, как буд-то он ещё активен, хотя уже нет.
Добавлено:
А, я понял :man_facepalming: Вы имеете ввиду, что расстояние между строчек слишком маленькое и они просто накладываются друг на друга! Я просто гений!
Вам надо яснее излагать мысли.
Но даже если так, то предыдущая активная строка всё равно должна перерисоваться. А как она это сделает?
Да, точно! Предыдущая активная строка перерисовывается автоматически. На WinAPI, вроде, так же сделано.