C# MouseLeave事件处理程序太慢

C# MouseLeave事件处理程序太慢,c#,.net,events,mouseleave,C#,.net,Events,Mouseleave,我使用MouseLeave事件检查用户是否离开了我的表单并关闭了我的窗口,但是使用 this.MouseLeave+=new System.EventHandler(this.InvisibleForm_离开) 太慢了,只有当我准备慢慢离开我的状态时,事件才会被触发,以正常的方式移动它/稍微快一点,我没有得到离开事件 因此,我尝试自己检查鼠标是否离开了我的窗体: private void checkPos() { Rectangle rec = this.Bounds;

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

因此,我尝试自己检查鼠标是否离开了我的窗体:

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)
检查该区域后,该区域仍然返回true,仅在一秒钟后,他将执行if代码,但有时他会在瞬间得到它

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

跨线程操作无效:从创建控件“MyForm”的线程以外的线程访问控件“MyForm”

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

  • 对于鼠标离开的部分,我不太确定。也许你可以试着通过MouseMove事件来处理这个问题
  • 对于无效的跨线程操作问题,您无法访问另一个线程拥有的控件(在您的例子中是UI线程)。使用或代替

  • 我不认为这里的问题是鼠标的性能。我使用MouseLeave(与MouseEnter和MouseMove结合使用)自动淡入/淡出表单。它是有效的:)。 这是一个带有标签的示例表单:

    如果标签和表单都处理了MouseLeave,那么不管我移动鼠标的速度有多快,事件处理程序都会触发。例如:

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

    因此,我认为正在发生的是,表单的子控件正在触发MouseLeave事件,而您没有处理该事件。当您缓慢移动鼠标时看到事件激发的原因是,您在窗体区域上悬停的时间足以生成事件


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

    我遇到了同样的问题,那么做:

  • 把计时器放在表格里
  • 将代码放入计时器滴答声事件中,如鼠标离开:

    Label1.BackColor=Color.PaleGreen;
    
  • 将计时器间隔设置为小于30

  • 使用此功能

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        timer1_Tick(label1(example), e); 
    }
    
  • 将其放入formload事件中

    timer1.Tick += timer1_Tick;
    

  • 代码将运行得非常快速和简单,您将再也看不到类似的问题了

    它可能很慢的原因是
    线程。Sleep(500)在那个时间段内抓不到你的鼠标我把它设置为100毫秒,500毫秒只是为了测试1的可能重复。我想我遇到了问题,我正在更改表单中的大小,当检查rec时,他保存了旧的大小边界,而不是更改2后的新大小边界。我会试试它的,只要我有一个边框就行了,但是当使用这个的时候。FormBorderStyle=FormBorderStyle.None;对于我的表格,它也有同样的问题。你可以发布一个小样本来解决这个问题吗?我通常这样做是为了淡出无边框的弹出窗口,效果很好。我认为表单边框样式不应该对MouseLeave事件有任何影响。通常使用计时器来解决这些问题是个坏主意。你已经有了一个可以处理的事件,所以你应该坚持下去。