2012-04-20 1 views
1

Я использую событие MouseLeave, чтобы проверить, если пользователь оставил свою форму и закрыть свое окно, но с использованием this.MouseLeave += new System.EventHandler(this.InvisibleForm_Leave); слишком медленно, только если я буду оставить свою форму медленно событие запускается, перемещая его обычным способом/немного быстрее. Я не получаю событие отпуска.MouseLeave EventHandler слишком медленно

Поэтому я попытался проверить на моем собственном, если мышь оставила свою форму или нет:

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

Но с этим у меня есть более или менее та же проблема, оставив область по-прежнему возвращает true после проверки ее rec.Contains(point) только после того, как он выполнит код if, но иногда он получает его в одно мгновение.

Вторая проблема состоит в том, что я получаю исключение нить в this.Close(); линии в checkPost() метода:

операции кросс-нить не действует: Control «MyForm» доступ из потока, отличного поток, на котором он был создан.

Теперь я действительно не знаю, как реализовать мышь, оставляя часть по-другому.

+0

Причина может быть медленным, является 'Thread.Sleep (500),' не поймать мышь в этот период времени –

+0

у меня было это на 100 мс, 500 мс было только для проверки – dontcare

+0

возможного дубликата [Затухание и исчезновение формы] (http://stackoverflow.com/questions/2927955/fading-in-and- fading-out-for-a-form) –

ответ

2
  1. Для мыши, оставляющей часть, я не совсем уверен. Может быть, вы можете попытаться справиться с этим событием MouseMove?
  2. Для недопустимой проблемы с перекрестной резьбой вы просто не можете получить доступ к элементу управления, принадлежащему другому потоку (это поток пользовательского интерфейса в вашем случае). Используйте вместо этого Control.BeginInvoke или Control.Invoke.
+0

1. Я думаю, что у меня возникла проблема, я меняю размер из формы, и при проверке rec он получил старые ограничения, а не новые границы размера после изменения 2 . попробуем это – dontcare

+0

после использования вызова с делегатом все отлично работает – dontcare

+0

@dontcare Рад узнать, что – Hailei

3

Я не думаю, что проблема с MouseLeave является проблемой здесь. Я использовал 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)); 
} 

Однако, если удалить обработчик MouseLeave для label1, я в состоянии воспроизвести поведение, которое вы видите. Если я медленно перемещаю мышь с метки1 (оранжевый) на форму (зеленый) и снаружи, событие срабатывает. Если я быстро перемещаю мышь с метки1 на внешнюю часть формы, это событие не срабатывает.

Итак, , что я думаю, происходит в том, что дочерний элемент управления вашей формы запускает событие MouseLeave, и вы не обрабатываете это событие. Причина, по которой вы видите событие, когда вы двигаете мышь медленно, - это то, что вы нависаете над областью формы, достаточно длинной для создания события.

Кроме того, нереста отдельного потока для мониторинга событий MouseLeave не является хорошим подходом.Ваша производительность будет страдать, поскольку этот поток опросит состояние события (в отличие от ожидания события), вы создаете ненужную головную боль для запуска/остановки потоков, и вам нужно будет возвращать обратно в поток пользовательского интерфейса всякий раз, когда вы хотите сделать что-нибудь с формой (как вы узнали). Если у вас есть время пересмотреть подход к событию MouseLeave, я настоятельно рекомендую вам это сделать. Удачи!

+0

попробовал, так что у меня есть граница, работающая нормально, но при использовании this.FormBorderStyle = FormBorderStyle.None; для моей формы у нее одинаковые проблемы – dontcare

+0

Можете ли вы разместить небольшой образец с проблемой? Я обычно делаю это для выцветания всплывающих окон всплывающих окон без полей, и он отлично работает. Я не думаю, что стиль рамки формы должен иметь какое-либо влияние на события MouseLeave. –

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

Обычно это плохая идея использовать таймеры для таких проблем. У вас уже есть событие, с которым вы можете справиться, поэтому его следует придерживаться. –