2012-04-20 59 views
1

我使用MouseLeave事件,以检查用户是否离开了我的形式,并关闭我的窗口,但使用 this.MouseLeave += new System.EventHandler(this.InvisibleForm_Leave); 太慢,只有当我要离开我的形式缓慢事件被解雇,以正常方式移动/更快一点我没有得到假期事件。鼠标离开事件处理程序太慢

所以我想检查我自己当鼠标离开了我的形式或不:

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); 
     } 
    } 

开始在自己的线程创建窗体后:

public MyForm() 
    { 
     InitializeComponent(); 
     Thread m_mouseListenerThread = new Thread(new ThreadStart(this.checkPos)); 
     m_mouseListenerThread.Start();    
    } 

但是有了这个,我有或多或少同样的问题,离开该地区唯一的一秒钟之后仍然返回与rec.Contains(point)检查之后真他打算如果代码来执行的,但有时他得到它在瞬间。

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

跨线程操作无效:控制'MyForm的距离比其他线程访问它创建的线程。

现在我真的不知道如何实现鼠标以其他方式留下部分。

+0

它可能是缓慢的原因是'Thread.sleep代码(500);'不赶你的鼠标在那段时间内 – 2012-04-20 11:42:43

+0

我有它为100ms,500ms的所述仅为测试[淡入淡出为表单]的 – dontcare 2012-04-20 11:45:03

+0

可能重复(http://stackoverflow.com/questions/2927955/fading-in-and-淡出换一个形式) – 2012-04-20 11:59:53

回答

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

1.我想我的问题,我改变了从形式的规模和检查REC时,他得到了老界保存,而不是改变2后的新尺寸范围。会尝试使用 – dontcare 2012-04-20 11:51:56

+0

后使用委托调用一切正常 – dontcare 2012-04-20 12:13:18

+0

@dontcare高兴知道 – Hailei 2012-04-20 12:14:17

3

我不认为鼠标离开性能是这里的问题。我用鼠标离开(与的MouseEnter和mousemove组合)来自动淡入/淡出形式。有用 :)。 下面是一个示例形式只是一个标签:

如果鼠标离开是为标签和表单都处理,事件处理始终闪光无论我如何快速移动鼠标。例如:

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的MouseLeave处理程序,我能够重现您所看到的行为。如果我将鼠标从标签1(橙色)缓慢移动到窗体(绿色)和外部,则会触发事件。如果我将鼠标从label1快速移动到表单之外,则该事件不会触发。

因此,我认为正在发生的事情是您的窗体的子控件正在触发MouseLeave事件,并且您没有处理该事件。当您慢慢移动鼠标时,您看到事件触发的原因是因为您在表单区域上空盘旋足以产生事件。

此外,产生一个单独的线程来监视MouseLeave事件不是一个好方法。你的成绩将受到影响,因为这线程轮询事件状态(而不是等待一个事件),您要创建启动的不必要的头痛/停止线程,你需要,只要你想调用返回到UI线程对表格做任何事情(如你所知)。如果您有时间重新访问MouseLeave事件方法,我强烈建议您这样做。祝你好运!

+0

试了一下,这么久了,我有它工作正常,但使用this.FormBorderStyle = FormBorderStyle.None当边界;对于我的表格它有相同的问题 – dontcare 2012-04-23 07:58:09

+0

你能发表一个小样本的问题吗?我通常为淡入淡出弹出式无边界弹出式窗口做到这一点,它工作正常。我不认为窗体边框样式应该对MouseLeave事件有任何影响。 – 2012-04-23 12:30:17

0

我面临同样的问题,做到这一点:

  1. 放定时器的形式。
  2. 代码放在计时器滴答事件如鼠标离开:

    Label1.BackColor=Color.PaleGreen; 
    
  3. 设置计时器的时间间隔不到30

  4. 使用此功能

    protected override void OnLoad(EventArgs e) 
    { 
        base.OnLoad(e); 
        timer1_Tick(label1(example), e); 
    } 
    
  5. 在formload将这个事件

    timer1.Tick += timer1_Tick; 
    

的代码将运行速度非常快,易,你永远不会看到任何这样的问题再次

+0

通常使用定时器来解决这些问题是一个坏主意。你已经有一个可以处理一个事件,所以应该坚持下去。 – 2017-01-30 09:46:04