2010-08-02 126 views
5

由于无法解决问题(原始here),我正在重新发布此问题。MouseLeave事件在控件的滚动条上移动时触发

在TreeView,ListBox中,或者它似乎从我的谷歌搜索任何与ScrollBar,ScrollBar不被视为控件的一部分。

我有一个TreeView,我把它放在一个自定义控件中,它是Dock填充。所以它就像一个自定义的TreeView一样,它拥有我们所有的逻辑来管理它。

在我们的程序的某些部分,我们根据MouseEnter事件将其滑出,然后将其滑回到MouseLeave事件中,但是我们目前正在使用第三方库的TreeView来执行此操作,因此我一直负责进行替换。

所以我把所有的东西都移到了Windows的TreeView中,但是找不到一个方法来可靠地捕获MouseLeave - 只有它离开了整个TreeView,包含了滚动条。

我已经看到了一个黑客解决方案,将它包装在一个具有几个像素的面板中,并捕获面板的MouseLeave,但我几乎不相信这是微软在这种情况下打算做的。

在短:

的滚动条不火的MouseEnter或鼠标离开的控制,这使得使用的MouseEnter /鼠标离开滑动了控制,因为用户无法使用滚动条无法使用。

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

在上一个问题中,我得到了使用Spy ++的建议,并试图附加到WndProc()来处理ScrollBar的MouseEnter/MouseLeave。

但是,这并没有工作,因为Spy ++显示的消息没有在WndProc()的窗体级别或控件级别触发。就好像.NET不能看到ScrollBar一样。使用WndProc()对于这样一个简单的请求似乎也是不切实际的,是否有任何其他方式来做到这一点,或者如果WndProc()是唯一的方法,有没有人真的能够实现这一点,并告诉我怎么做?

回答

4

对此没有干净的解决方案。您的面板技巧也无法使用,当用户快速移动鼠标时,它将完全错过。

平底船。一旦你得到MouseEnter,启动一个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事件的工作原理也是顺便说一句,稍微有些尴尬。

+0

这工作完美,谢谢! – 2011-01-11 19:16:48

2

感谢提示有同样的问题,我修改了timer_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; 
     } 
    }