判断鼠标是否在表单上的最佳方法是什么?我想出了如何捕获整个窗体上的鼠标点击,但这种方法不能很好地转换为MouseEnter和MouseLeave。我的表单布局由许多Panels和TableLayoutPanels组成,因此我无法监视事件的全面控制,显然Button的MouseLeave事件并不意味着光标离开整个表单。有没有人想出解决这个问题的好方法?正如有人在这里指出的那样,可以使用SetWindowsHookEx()或将MouseMove事件连接到表单中的所有控件。后者对我来说很好用。唯一的缺点是如果在运行时添加/删除控件,可能需要其他解决方案。使用系统;使用系统绘图;使用System.Windows.Forms;namespaceWindowsForms_MouseEvents{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();鼠标移动+=OnMouseMove;MouseLeave+=OnMouseLeave;HookMouseMove(this.Controls);}privatevoidHookMouseMove(Control.ControlCollectionctls){foreach(Controlctlinctls){ctl.MouseMove+=OnMouseMove;HookMouseMove(ctl.Controls);}}privatevoidOnMouseMove(objectsender,MouseEventArgse){BackColor=Color.Plum;控制ctl=发送者作为控制;if(ctl!=null){//将鼠标坐标映射到Pointloc=this.PointToClient(ctl.PointToScreen(e.Location));Console.WriteLine("鼠标在{0},{1}",loc.X,loc.Y);}}privatevoidOnMouseLeave(objectsender,EventArgse){BackColor=Color.Gray;}}}一个开始的地方是检查ClientRectangle是否包含当前鼠标位置。因此,例如,在您的MouseMove处理程序上,您可以:}以合理的间隔(可能是50毫秒)向表单添加一个计时器。在Tick事件处理程序中使用此代码查看鼠标当前是否在窗体上://检查鼠标当前是否在窗体上booltemp_mof=ClientRectangle.Contains(Form.MousePosition.X-Location.X,Form.MousePosition.Y-位置.Y);编辑:这是一个更完整的解决方案,用于检测鼠标是否在表单上并且是否已单击按钮。timer1Tick()是窗体上计时器的Tick事件处理程序。无需为窗体上的其他控件添加额外的事件处理程序。这将使用您的表格“一个巨大的按钮”:)boolm_mouse_over_form=false;//假设左键在开始时按下boolm_left_button_down=true;voidtimer1Tick(objectsender,EventArgse){//检查鼠标当前是否在表单上booltemp_mof=ClientRectangle.Contains(Form.MousePosition.X-Location.X,Form.MousePosition.Y-Location.Y);//在此滴答声之前我们是否已经完成了表单?if(temp_mof&&m_mouse_over_form){//我们需要检测鼠标的按下和向上以避免//如果按住鼠标按钮的时间超过我们的Tick间隔//鼠标按钮在现在之前是否向上?if(!m_left_button_down){//按钮现在按下了吗?m_left_button_down=(MouseButtons==MouseButtons.Left);if(m_left_button_down){//按钮被按下,现在已被释放LeftButtonClickHandler();}else{//什么都不做,按钮还没有释放}}else{//更新按钮状态m_left_button_down=(MouseButtons==MouseB按钮。左);}}elseif(temp_mof){//鼠标刚刚进入表格m_mouse_over_form=true;//设置左键的初始状态m_left_button_down=MouseButtons==MouseButtons.Left);}else{//鼠标当前不在表单上m_mouse_over_form=false;m_left_button_down=true;我找到了一些接近我想要的答案,但我做的不同我想检测鼠标是否离开了表单区域(包括标题栏),这对我有用:在表单构造函数中,我添加了一个定时器:time.Interval=250;time.Tick+=time_Tick;时间.开始();然后在tick方法中,我执行以下操作:voidtime_Tick(objectsender,EventArgse){switch(RectangleToScreen(Bounds).Contains(PointToScreen(Cursor.Position))){casetrue:if(Opacity!=.9999D)不透明度=.9999D;休息;casefalse:if(Opacity!=.5D)Opacity=.5D;休息;}}在Form和Form控件上执行MouseEnter和MouseLeave事件;使用布尔值来判断鼠标是进入还是离开。一个例子是privatestaticboolmouseEnteredFormprivatevoidForm1_MouseMove(objectsender,MouseEventArgse){mouseEnteredForm=true;Form.MouseLeave+=Form1_MouseLeave;检查鼠标位置();}privatevoidForm1_MouseLeave(objectsender,MouseEventArgse){mouseEnteredForm=falseCheckMouseLocation();}privatestaticvoidCheckMouseLocation(){if(!mouseOverForm){MessageBox。Show("MouseNotOverForm!);}elseif(mouseOverForm)//elseif是可选的。你也可以在这种情况下使用else。为了示例,我使用了elseif。{MessageBox.Show("MouseIsOverForm");}}如果窗体上有很多对象,这会变得很乏味窗体上方最好的方法?所有内容共享,如果对你有用,你需要了解更多C#学习教程,我希望大家多多关注,本文收集自网络,不代表立场,如涉及侵权,请点击右边联系管理员删除,如需转载请注明出处:
