Состояние ListBox DrawItem HotLight в режиме OwnerDraw? - PullRequest
7 голосов
/ 22 августа 2009

Я использую OwnerDrawFixed в качестве DrawMode для пользовательского элемента управления ListBox в моем приложении WinForms.

Я хочу перекрасить фон (или выполнить другое действие) ListBoxItem, когда пользователь наводит курсор на элемент списка, то есть на MouseMove ...

DrawItemState.HotLight никогда не работает для ListBox, поэтому мне интересно, как его эмулировать, как обойти эту проблему.

Ответы [ 2 ]

11 голосов
/ 05 августа 2011

Мне понадобилось всего два года, чтобы найти ответ для вас, но вот он:

DrawItemState.HotLight применяется только к нарисованным владельцем меню, а не к списку. Для ListBox вы должны следить за элементом самостоятельно:

public partial class Form1 : Form
{
  private int _MouseIndex = -1;

  public Form1()
  { InitializeComponent(); }

  private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
  {
    Brush textBrush = SystemBrushes.WindowText;

    if (e.Index > -1)
    {
      if (e.Index == _MouseIndex)
      {
        e.Graphics.FillRectangle(SystemBrushes.HotTrack, e.Bounds);
        textBrush = SystemBrushes.HighlightText;
      }
      else
      {
        if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
        {
          e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds);
          textBrush = SystemBrushes.HighlightText;
        }
        else
          e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
      }
      e.Graphics.DrawString(listBox1.Items[e.Index].ToString(), e.Font, textBrush, e.Bounds.Left + 2, e.Bounds.Top);
    }
  }

  private void listBox1_MouseMove(object sender, MouseEventArgs e)
  {
    int index = listBox1.IndexFromPoint(e.Location);
    if (index != _MouseIndex)
    {
      _MouseIndex = index;
      listBox1.Invalidate();
    }
  }

  private void listBox1_MouseLeave(object sender, EventArgs e)
  {
    if (_MouseIndex > -1)
    {
      _MouseIndex = -1;
      listBox1.Invalidate();
    }
  }
}
0 голосов
/ 16 июня 2015

Это решение просто утяжелит ваш код; просто попробуйте это:

If e.State And DrawItemState.Selected Then
                    e.Graphics.FillRectangle(SystemBrushes.HotTrack, e.Bounds)
                    e.Graphics.DrawString(drv, Me.Font, SystemBrushes.HighlightText, e.Bounds.X + 18, e.Bounds.Y + 1)
                Else
                    e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds)
                    e.Graphics.DrawString(drv, Me.Font, SystemBrushes.ControlText, e.Bounds.X + 18, e.Bounds.Y + 1)
End If

Эта операция: e.State And DrawItemState.Selected проверяет, находится ли элемент в поиске. Не нужно ставить целый пакет кода, чтобы узнать, что за предмет находится.

...