zoukankan      html  css  js  c++  java
  • WinForm中MouseEnter和MouseLeave混乱的问题

      MouseEnter+MouseLeave不行,我用了MouseMove+MouseLeave,效果一样

      最近做个聊天的系统,仿照qq的界面设计,像qq聊天界面中字体、表情、截图等图片,鼠标放上去显示边框,所以很自然用到了enter和leave这两个事件,因为是picturebox控件没有over和out事件,但调了两个小时就是不行,mouseleave事件不灵,经常不触发,也不是速度太快造成的,因为有时快也能触发,我慢慢经过反倒经常不触发,头疼,因为我这些图片外面套的有两层panel,网上查了些资料看了,说鼠标在控件上也算不在panel上,但和我的情况不符合呀,整了一下午不行,放弃(最后终于知道是因为Leave是在离开控件边缘的一瞬间触发,但我进入控件后加了边框,所以鼠标离开控件边缘时,是在后加上的边框上,依然认为在控件里,导致慢慢经过边缘不触发,但Enter事件不能控制,所以还得用下面的);

      没办法开始尝试用判断鼠标是否在控件上这个方法,这里用到的是mousemove事件,这里也有坑,什么相对于屏幕的坐标和相对于窗口的,也是整的有点云里雾里的。先看下最终实现的效果,:

      private void picBoxLog_MouseMove(object sender, MouseEventArgs e)
            {
                Point p = flowLayoutPanel2.PointToClient(Control.MousePosition);//flowLayoutPanel2是picBoxLog的父容器
                int side = 1;//决定于边框的宽度
                if (p.X > picBoxLog.Location.X + side && p.X < picBoxLog.Location.X + picBoxLog.Width - side && p.Y > picBoxLog.Location.Y + side && p.Y < picBoxLog.Location.Y + picBoxLog.Height - side)
                {
                    picBoxLog.BorderStyle = BorderStyle.FixedSingle;
                }
                //else
                //    picBoxLog.BorderStyle = BorderStyle.None;
            }

    开始只用move,但移出控件上就不触发该事件,所以不会去掉边框,尝试鼠标进入控件过一段距离后加边框,四周留一些边距,触发去掉边框(看上面的代码我加了side就知道了,所以大家就不用加side了),但如果移动过快也会造成去不掉的情况,虽然不容易发生,而且控件本来就30高度没多大,我两边都留了8,还是会发生,再多点就没了,灵光一闪,把去掉边框的方法,又放到了Leave事件中,日了狗了,这两个事件竟完美配合,想砸键盘的心都有了,所以记录下来,献给正在为此砸键盘或将来可能砸键盘的猿猿们。

    贴一下用这个方法过程中查看的知识点:

    1)PointToClient 将指定屏幕点的位置计算成工作区坐标。坐标原点为黄色区域左上角,X轴方向从左到右;Y轴方向从上到下;坐标单位为像素;

    2)PointToScreen 将指定工作区点的位置计算成屏幕坐标。坐标原点在屏幕左上角,X轴方向从左到右;Y轴方向从上到下;坐标单位为像素;

    获取鼠标的位置的:

      很多时候我们需要用到鼠标在相对于窗体上的坐标,或者相对于屏幕的坐标,这里就把我的经验记录下。

      用Control.MousePosition获得当前鼠标的坐标CurrentPoint,使用Control.PointToClient方法,前面获得的CurrentPoint作为其参数,返回的Point类型的对象即为鼠标相对于某个控件的坐标。

    现在以鼠标相对于窗体的坐标做为例子,如下:   

              Point screenPoint = Control.MousePosition;//鼠标相对于屏幕左上角的坐标           

       Point formPoint = this.PointToClient(Control.MousePosition);//鼠标相对于窗体左上角的坐标

    同理:

                Point button1Point= button1Point.PointToClient(Control.MousePosition); //鼠标相对于button1左上角的坐标

    还有Control.PointToScreen方法,返回的是相对于屏幕的坐标。

        大概就这些吧,中间还试了Rectangle相关的,没成功,不知道是不是哪写错了,哪位大神知道了,可以指点下

        //Rectangle rec = picBoxLog.RectangleToClient(this.ClientRectangle);
                //Point p = flowLayoutPanel2.PointToClient(Control.MousePosition);  flowLayoutPanel2是picBoxLog的父容器,改成this也试了不行
                //if (rec.Contains(p))
                //{
                //    picBoxLog.BorderStyle = BorderStyle.FixedSingle;
                //}
                //else
                //    picBoxLog.BorderStyle = BorderStyle.None; 

  • 相关阅读:
    20200804 千锤百炼软工人第三十天
    20200803 千锤百炼软工人第二十九天
    20200802 千锤百炼软工人第二十八天
    小谢第51问:从输入url到浏览器显示页面发生了什么
    小谢第50问:vuex的五个属性-使用-介绍
    小谢第49问:URL都由什么组成
    小谢第48问:js跳转页面与打开新窗口的方法
    小谢第47问:vue项目中,assets和static的区别
    小谢第46问:js事件机制
    小谢第45问:Ajax 是什么? 如何创建一个 Ajax
  • 原文地址:https://www.cnblogs.com/dachuang/p/5717525.html
Copyright © 2011-2022 走看看