如果鼠标进入C#ListView的滚动条,则显示工具提示

时间:2013-12-19 10:16:51

标签: c# listview tooltip scrollbar

一旦鼠标光标进入System.Windows.Forms.ListView的垂直滚动条,我想显示工具提示。对于DataGridView来说,它很容易,因为有一个滚动条的引用,我可以使用它来处理MouseEnter / MouseLeave事件。

当鼠标悬停在滚动条上时,甚至不会触发ListView的MouseMove事件。有没有解决这个问题的方法?

2 个答案:

答案 0 :(得分:1)

当鼠标指针进入或离开正在“监视”的控件时,ControlWatcher类会引发事件。它允许您捕获多个控件的鼠标事件,或者停止捕获这些事件。

public partial class Form1 : Form
{
    public ToolTip toolTip { get; set; }

    public Form1()
    {
        InitializeComponent();
        toolTip = new ToolTip();

        var watcher = new ControlWatcher();
        watcher.MouseEnter += watcher_MouseEnter;
        watcher.MouseLeave += watcher_MouseLeave;
        watcher.AddControl(listView1);
        watcher.StartListening();
    }

    void watcher_MouseEnter(Control control)
    {
        var pt = control.PointToClient(Cursor.Position);
        toolTip.Show("Super tooltip", control, pt);
    }

    void watcher_MouseLeave(Control control)
    {
        toolTip.Hide(control);

    }
}

public class ControlWatcher : IMessageFilter
{
    public event Action<Control> MouseEnter;
    public event Action<Control> MouseLeave;

    private Control lastControl;

    private List<Control> controls;

    public ControlWatcher()
    {
        controls = new List<Control>();
    }

    public void StartListening()
    {
        Application.AddMessageFilter(this);
    }

    public void StopListening()
    {
        Application.RemoveMessageFilter(this);
    }

    public void AddControl(Control c)
    {
        controls.Add(c);
    }

    private bool IsMouseOverControl(Control control)
    {
        var pt = control.PointToClient(Cursor.Position);
        var isOver = (pt.X >= 0 && pt.Y >= 0 && pt.X <= control.Width && pt.Y <= control.Height);
        return isOver;
    }

    private void OnMouseEnter(Control control)
    {
        if (MouseEnter != null)
            MouseEnter(control);
    }

    private void OnMouseLeave(Control control)
    {
        if (MouseLeave != null)
            MouseLeave(control);
    }

    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg != 675 && m.Msg!=512)
        {
            return false;
        }
        //the control under the cursor
        var actControl = controls.FirstOrDefault(IsMouseOverControl);

        if (lastControl != null && actControl == null)
        {
            OnMouseLeave(lastControl);
            lastControl = null;
            return false;
        }

        if (lastControl==null && actControl != null && actControl != lastControl)
        {
            lastControl = actControl;
            OnMouseEnter(actControl);
            return false;
        }
        return false;
    }
}

答案 1 :(得分:0)

作为对已接受答案的补充,这是我用来检测鼠标是否在水平,垂直或无滚动条上的方法:

    private ScrollBars IsMouseOverScrollbar(ListView dlv)
    {
        var pt = dlv.PointToClient(Cursor.Position);
        var isOverScrollbar = (pt.X >= 0 && pt.Y >= 0 && pt.X <= dlv.Width && pt.Y <= dlv.Height) && !dlv.ClientRectangle.Contains(pt);

        if (isOverScrollbar)
        {
            // the mouse is over some scrollbar
            if (dlv.Bounds.Width - pt.X > dlv.Bounds.Height - pt.Y)
            {
                // mouse pointer is within the horizontal scrollbar
                return ScrollBars.Horizontal;
            }
            else
            {
                // mouse pointer is within the vertical scrollbar
                return ScrollBars.Vertical;
            }
        }

        return ScrollBars.None;
    }