一旦鼠标光标进入System.Windows.Forms.ListView的垂直滚动条,我想显示工具提示。对于DataGridView来说,它很容易,因为有一个滚动条的引用,我可以使用它来处理MouseEnter / MouseLeave事件。
当鼠标悬停在滚动条上时,甚至不会触发ListView的MouseMove事件。有没有解决这个问题的方法?
答案 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;
}