Control With Scrollbar上的.NET C#MouseEnter侦听器
只要鼠标位于特定控件上,我们就会显示某种forms。 当鼠标离开控件时,我们会在超时后隐藏控件。 这是标准的hover行为。
但是,当控件(例如Treeview)具有滚动条,并且鼠标为ON或滚动条时,事件不会触发…
如果我们可以获得对滚动条控件的引用,这将解决我们的问题,因为我们会将相同的侦听器事件添加到滚动条。 但是,据我所知,滚动条无法访问…
我们怎样才能解决这个问题?
滚动条位于树视图的非客户区域中。 当鼠标移动到那里时,它开始生成非客户端消息,如WM_NCMOUSEMOVE和WM_NCMOUSELEAVE。 您必须对TreeView进行子类化并覆盖WndProc()以检测这些消息。
这并没有真正解决你的问题,你仍然会遇到边缘情况。 使用Timer的低技术方法始终有效:
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(); } }
我认为有几种不同的方法可以做到这一点,但关键是你希望在行动上超时。 我认为两种技术的结合可能有效:
将控件放在面板上,停靠以填充,并使用面板的MouseEnter打开您的行为 – 这将包括控件的滚动条。 您也可以使用面板的MouseLeave事件,但是您必须检查光标的位置以确保它没有移动到包含的控件中。 这种方法最可靠,但快速移动鼠标可能会让人感到困惑。
如果将其与显示所显示/隐藏控件时启动的计时器结合使用,并定期检查光标位置。 这将起作用,但是在隐藏控件之前的超时不一定是一致的(因为计时器在进入控件时启动)。 您可以在控件中的mousemoves上停止/启动计时器以稍微缓解这种情况。
我整理了一个我在这里试过的不同方法的项目: http : //lovethedot.s3.amazonaws.com/100609StackoverflowScrollbarQuestion.zip
通过对接要在面板中跟踪的控件,它实际上将它包装起来,并且您将在跟踪控件的最边缘处获得MouseEnter:
private void panel1_MouseEnter(object sender, EventArgs e) { this.Text = "in"; } private void panel1_MouseLeave(object sender, EventArgs e) { if (!new Rectangle(new Point(0, 0), panel1.Size).Contains(panel1.PointToClient(Control.MousePosition))) this.Text = "out"; }
您正在跟踪进入控件周围的面板,并退出该面板,前提是光标不在跟踪控件内。
为了获得更好的“离开”体验,它与Timer一起检查以查看光标的位置:
上述就是C#学习教程:Control With Scrollbar上的.NET C#MouseEnter侦听器分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
private void listBox3_MouseEnter(object sender, EventArgs e) { button1.Visible = true; visibleTimer.Stop(); visibleTimer.Start(); } void visibleTimer_Tick(object sender, EventArgs e) { if (!new Rectangle(new Point(0, 0), listBox3.Size).Contains(listBox3.PointToClient(Control.MousePosition))) { visibleTimer.Stop(); button1.Visible = false; } }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/988776.html