如何在悬停时更改ListBox项的背景颜色?

时间:2014-12-22 15:27:05

标签: c# winforms listbox

当我将鼠标悬停在它上面时,如何更改ListBox项目的背景颜色?
我用这段代码覆盖了DrawItem事件:

private void DrawListBox(object sender, DrawItemEventArgs e)
{
    e.DrawBackground();         
    Graphics g = e.Graphics;
    Brush brush = ((e.State & DrawItemState.Selected) == DrawItemState.Selected) ?
        new SolidBrush(Color.FromArgb(52, 146, 204)) : new SolidBrush(e.BackColor);
    g.FillRectangle(brush, e.Bounds);

    e.Graphics.DrawString(listBox1.Items[e.Index].ToString(), e.Font,
         new SolidBrush(e.ForeColor), e.Bounds, StringFormat.GenericDefault);
    e.DrawFocusRectangle();
}

但是,ListBox没有包含悬停Item的Property。在ListBox上也没有像MouseEnterItem,MouseHoverItem事件或任何类似的事件可以订阅。

我做了很多研究,但我发现的所有内容都是关于SO的类似问题,它混淆了ListBox和ListView:Hightlight Listbox item on mouse over event

2 个答案:

答案 0 :(得分:2)

由于ListBox不提供MouseEnterItem和MouseHoverItem事件,因此必须自己编写此功能,跟踪鼠标的坐标以确定鼠标所在的项目。

以下问题非常相似,旨在显示每个项目悬停时的工具提示。 Michael Lang的答案是一个非常好的解决方法,应该适合您的目的:

How can I set different Tooltip text for each item in a listbox?

答案 1 :(得分:1)

你真的想要悬停吗? =>用户移动鼠标,然后停止一个点,延迟不再移动

如果您想立即获得反馈,请使用MouseMove()事件并使用IndexFromPoint()获取您结束的​​项目的索引。将该值存储在表单级别,以便您可以确定自上次移动后它是否已更改,然后在DrawListBox()处理程序中相应地设置背景填充颜色:

    private int prevIndex = -1;

    private void listBox1_MouseMove(object sender, MouseEventArgs e)
    {
        int index = listBox1.IndexFromPoint(listBox1.PointToClient(Cursor.Position));
        if (index != prevIndex)
        {
            prevIndex = index;
            listBox1.Invalidate();
        }
    }

    private void listBox1_MouseLeave(object sender, EventArgs e)
    {
        prevIndex = -1;
        listBox1.Invalidate();
    }

    private void DrawListBox(object sender, DrawItemEventArgs e)
    {
        e.DrawBackground();
        Graphics g = e.Graphics;

        Color c;
        if (e.Index == prevIndex )
        {
            c = Color.Yellow; // whatever the "highlight" color should be
        }
        else if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
        {
            c = Color.FromArgb(52, 146, 204); 
        }
        else
        {
            c = e.BackColor;
        }
        using (SolidBrush brsh = new SolidBrush(c))
        {
            g.FillRectangle(brsh, e.Bounds);
        }

        using (SolidBrush brsh = new SolidBrush(e.ForeColor))
        {
            g.DrawString(listBox1.Items[e.Index].ToString(), e.Font,
             brsh, e.Bounds, StringFormat.GenericDefault);
        }

        e.DrawFocusRectangle();
    }