代码之家  ›  专栏  ›  技术社区  ›  Brett Allen

在控件的滚动条上移动时触发MouseLeave事件

  •  5
  • Brett Allen  · 技术社区  · 14 年前

    here ).

    在我们的部分程序中,我们根据MouseEnter事件将其滑出,然后在MouseLeave事件中将其滑回,但是我们目前正在为此使用第三方库的TreeView,我的任务是替换它。

    我见过一个黑客的解决方案,把它包装在一个有几个像素的面板上,并捕捉到面板上的鼠标,但我几乎不相信这是微软打算让我们在这种情况下做的。

    简而言之:

    滚动条不会为控件启动MouseEnter或MouseLeave,这使得使用MouseEnter/MouseLeave滑出控件无法使用,因为用户不能使用滚动条。

    处理这种情况的首选方法是什么?

    在前面的问题中,有人建议我使用Spy++并尝试附加到WndProc()以处理滚动条的MouseEnter/MouseLeave。

    对于这样一个简单的请求,使用WndProc()似乎也是不现实的,有没有其他方法可以做到这一点,或者如果WndProc()是唯一的方法,有没有人能够做到这一点并告诉我如何做到?

    2 回复  |  直到 7 年前
        1
  •  4
  •   Hans Passant    14 年前

    没有干净的解决办法。你的面板技巧也不起作用,当用户快速移动鼠标时,它将被完全忽略。

    平底船。一旦你得到鼠标指针,启动一个200毫秒的计时器。在Tick事件中,检查鼠标是否仍悬停在树视图上。例如:

        private void treeView1_MouseEnter(object sender, EventArgs e) {
            timer1.Enabled = true;
            treeView1.Width = 220;
        }
    
        private void timer1_Tick(object sender, EventArgs e) {
            Point pos = treeView1.PointToClient(Cursor.Position);
            if (!treeView1.DisplayRectangle.Contains(pos)) {
                timer1.Enabled = false;
                treeView1.Width = 50;
            }
        }
    

    这个Application.Idle事件太有用了,只是有点尴尬。

        2
  •  2
  •   P Mic    8 年前

    感谢提示有同样的问题,我修改了timer\u Tick事件,将滚动条的宽度增加了20。

        private void tmrListPos_Tick(object sender, EventArgs e)
        {
            Point posLB = clbPlants.PointToClient(Cursor.Position);
            Rectangle rectPlants = clbPlants.DisplayRectangle;
            rectPlants.Width = rectPlants.Size.Width + 20;
            if (!rectPlants.Contains(posLB))
            {
                tmrListPos.Enabled = false;
                clbPlants.Size = clbPlants.MinimumSize;
            }
        }