7

OwnerDrawFixed在我的 WinForms 应用程序中用作自定义 ListBox 控件的 DrawMode。

当用户将鼠标悬停在列表框项目上时,我想重新绘制 ListBoxItem 的背景(或执行其他操作),即在 MouseMove ...

DrawItemState.HotLight从不适用于 ListBox,所以我想知道如何模拟它,如何解决这个问题。

4

2 回答 2

11

我只花了两年的时间为你找到答案,但这里是:

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();
    }
  }
}
于 2011-08-05T03:45:37.793 回答
0

该解决方案只会降低您的代码重量;试试这个:

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验证项目是否悬停。无需放置一整包代码即可知道悬停的项目。

于 2015-06-16T18:56:13.337 回答