首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MouseLeave eventhandler太慢

MouseLeave eventhandler太慢
EN

Stack Overflow用户
提问于 2012-04-20 11:40:28
回答 3查看 3K关注 0票数 2

我使用MouseLeave事件来检查用户是否离开了我的表单并关闭了我的窗口,但是使用this.MouseLeave += new System.EventHandler(this.InvisibleForm_Leave);太慢了,只有当我要慢慢离开表单时,事件才会被触发,以正常的方式/稍微快一点地移动它,我没有得到一个休假事件。

因此,我试图自己检查鼠标是否离开了我的表单:

代码语言:javascript
复制
private void checkPos()
    {
        Rectangle rec = this.Bounds;
        while (true)
        {
            Point point = new Point(Cursor.Position.X, Cursor.Position.Y);
            if (!rec.Contains(point))
            {
                Console.WriteLine("leaving");
                this.Close();                    
            }
            Thread.Sleep(100);
        }
    }

在创建表单后,在自己的线程中启动:

代码语言:javascript
复制
public MyForm()
    {
        InitializeComponent();
        Thread m_mouseListenerThread = new Thread(new ThreadStart(this.checkPos));
        m_mouseListenerThread.Start();            
    }

但是,有了这个问题,我或多或少也遇到了同样的问题,在使用rec.Contains(point)检查它之后,这个区域仍然返回true --只在他执行if代码之后,但有时他马上就会得到它。

第二个问题是,我在this.Close();方法中的checkPost()行中获得了一个线程异常:

跨线程操作无效:从创建线程以外的线程访问的控件'MyForm‘。

现在,我真的不知道如何用另一种方式实现鼠标离开部分。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-20 11:45:34

  1. 对于鼠标离开部分,我不太确定。也许你可以尝试通过MouseMove事件来处理这个问题?
  2. 对于无效的跨线程操作问题,您根本无法访问另一个线程拥有的控件(在您的情况下,它是UI线程)。使用Control.BeginInvokeControl.Invoke代替。
票数 2
EN

Stack Overflow用户

发布于 2012-04-20 12:42:13

我不认为MouseLeave性能是问题所在。我使用了MouseLeave (与MouseEnter和MouseMove一起)自动淡入/退出表单。它的作用是:)。这里有一个只有标签的示例表单:

如果同时处理标签和表单的MouseLeave,则不管移动鼠标的速度如何,事件处理程序总是会触发。例如:

代码语言:javascript
复制
this.label1.MouseLeave += new System.EventHandler(this.HandleMouseLeave);
this.MouseLeave += new System.EventHandler(this.HandleMouseLeave);

private void HandleMouseLeave(object sender, EventArgs e)
{
   Debug.WriteLine(string.Format("MouseLeave: {0}", DateTime.Now));
}

但是,如果我移除label1的label1处理程序,我就能够再现您正在看到的行为。如果我慢慢地将鼠标从label1 (橙色)移动到窗体(绿色)和外部,事件就会触发。如果我快速地将鼠标从label1移动到窗体外部,则事件不会触发。

所以,我认为正在发生的是,窗体的一个子控件正在触发一个MouseLeave事件,而您没有处理该事件。当您缓慢移动鼠标时,您会看到事件触发,原因是您在窗体区域上盘旋的时间足够长,足以产生事件。

此外,生成一个单独的线程来监视MouseLeave事件并不是一种好方法。当此线程轮询事件状态(而不是等待事件)时,您的性能将受到影响,您正在创建启动/停止线程的不必要的头痛,并且每当您想要对表单执行任何操作时,都需要在UI线程上调用(正如您所了解的)。如果您有时间重新讨论MouseLeave事件方法,我强烈建议您这样做。祝好运!

票数 3
EN

Stack Overflow用户

发布于 2017-01-30 09:38:38

我也面临着同样的问题,那就是:

  1. 把计时器装好。
  2. 将您的代码放入像鼠标离开这样的计时器滴答事件中: Label1.BackColor=Color.PaleGreen;
  3. 将计时器间隔设置为小于30
  4. 使用这个函数 保护覆盖无效OnLoad(EventArgs e) { base.OnLoad(e);timer1_Tick(label1(例如),e);}
  5. 将其置于formload事件中。 定时器1.timer1_Tick += timer1_Tick;

代码将运行非常快和容易,您将不会再看到任何这样的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10245539

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档