在控制滚动条.NET C#的MouseEnter监听器监听器、滚动条、NET、MouseEnter

2023-09-03 16:18:22 作者:坏坏小情人

只要鼠标在一个特定的控制,我们表现出一定的形式。当鼠标离开控件,我们躲在后小超时控制。这是标准的悬停行为。

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