只要鼠标在一个特定的控制,我们表现出一定的形式。当鼠标离开控件,我们躲在后小超时控制。这是标准的悬停行为。
As long as the mouse is over a specific control, we show some form. When the mouse leaves the control, we hide the control after a small timeout. This is standard hover behavior.
然而,当一个控制(例如树视图)有一个滚动条,并且鼠标上或上方的滚动条,该事件不火......
However, when a control (for example a Treeview) has a scrollbar, and the mouse is ON or OVER the scrollbar, the events don't fire ...
如果我们可以得到一个参考滚动条控制,这样可以解决我们的问题,我们将添加相同的监听事件的滚动条。然而,滚动条是无法访问,据我所知...
If we could get a reference to the scrollbar control, this would solve our problem, as we would add the same listener events to the scrollbar. However, the scrollbar isn't accessible as far as I know ...
我们如何解决这个问题呢?
How can we solve this problem ?
滚动条是树视图的非客户区。当鼠标移到那里,它开始产生像WM_NCMOUSEMOVE和WM_NCMOUSELEAVE非客户端的消息。你将不得不子类的TreeView和覆盖的WndProc()来检测这些消息。
The scrollbar is in the tree view's non-client area. When the mouse moves there, it starts generating non-client messages like WM_NCMOUSEMOVE and WM_NCMOUSELEAVE. You would have to sub-class the TreeView and override WndProc() to detect these message.
这并不能真正解决您的问题,虽然,你仍然有一个很难与边缘情况。一个带计时器的低技术的方法总是工作:
This doesn't really solve your problem though, you'll still have a hard time with edge cases. A low-tech approach with a Timer always works:
private Form frmPopup;
private void treeView1_MouseEnter(object sender, EventArgs e) {
timer1.Enabled = true;
if (frmPopup == null) {
frmPopup = new Form2();
frmPopup.StartPosition = FormStartPosition.Manual;
frmPopup.Location = PointToScreen(new Point(treeView1.Right + 20, treeView1.Top));
frmPopup.FormClosed += (o, ea) => frmPopup = null;
frmPopup.Show();
}
}
private void timer1_Tick(object sender, EventArgs e) {
Rectangle rc = treeView1.RectangleToScreen(new Rectangle(0, 0, treeView1.Width, treeView1.Height));
if (!rc.Contains(Control.MousePosition)) {
timer1.Enabled = false;
if (frmPopup != null) frmPopup.Close();
}
}