Question

I'm using OwnerDrawFixed as a DrawMode for the custom ListBox control in my WinForms app.

I want to repaint the background (or do some other action) of the ListBoxItem when the user hovers over the listbox item, that is, at the MouseMove...

DrawItemState.HotLight never works for the ListBox, so i wonder how to emulate it, how to workaround this problem.

Was it helpful?

Solution

It took me only two years to find the answer for you, but here it is:

The DrawItemState.HotLight only applies to owner drawn menus, not the listbox. For the ListBox, you have to keep track of the item yourself:

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();
    }
  }
}

OTHER TIPS

This solution will just weigh your code down; just try this:

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

This operation: e.State And DrawItemState.Selected verifies the item is hovered. No need to put a whole pack of code just to know what item is hovered.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top