由于无法解决问题,我正在重新发布此问题(原始here)。
在TreeView,ListBox中,或者似乎我的谷歌搜索任何带有ScrollBar的东西,ScrollBar不被视为控件的一部分。
我有一个TreeView,我将其放入自定义控件,它是Dock Fill。因此,它充当了一个自定义TreeView,它具有我们在一个地方管理它的所有逻辑。
在我们程序的某些部分中,我们根据MouseEnter事件将其滑出,然后在MouseLeave事件中将其滑回,但是我们当前正在使用第三方库的TreeView,我已经负责替换它。 / p>
所以我已经把所有内容都移到了Windows TreeView上,但如果它离开整个TreeView,包括滚动条,就找不到可靠捕获MouseLeave -only-的方法。
我已经看到了一个将它包装在一个带有几个像素的面板中并捕获面板的MouseLeave的一种破解解决方案,但我几乎不相信这是微软在这种情况下打算做的事情。
简而言之:
ScrollBar不会为控件触发MouseEnter或MouseLeave,这使得使用MouseEnter / MouseLeave滑出控件不可用,因为用户无法使用ScrollBar。
处理这种情况的首选方法是什么?
在上一个问题中,我获得了使用Spy ++的建议并尝试附加到WndProc()以处理ScrollBar的MouseEnter / MouseLeave。
然而这并不起作用,因为Spy ++显示的消息没有在窗体级别或控件级别的WndProc()中触发。这就好像.NET无法看到ScrollBar。
对于这样一个简单的请求,使用WndProc()似乎也不现实,有没有其他方法可以做到这一点,或者如果WndProc()是唯一的方法,有没有人真正能够实现这一点并告诉我如何?
答案 0 :(得分: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事件也很麻烦,只是有点尴尬。
答案 1 :(得分: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;
}
}