2012-04-20 58 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