Событие MouseMove в PictureBox запускается постоянно, даже если мышь не перемещается

Почему кажется, что событие MouseMove для PictureBox запускается постоянно, даже если мышь не перемещается? Я пробовал следующие коды, чтобы доказать это (просто создав новую форму с PictureBox и меткой на ней).

private void pictureBox1_MouseMove ( object sender, MouseEventArgs e )
{
  label1.Text = DateTime.Now.ToLongTimeString ( ) + ": " + e.X + "," + e.Y;
}

person Setyo N    schedule 12.12.2011    source источник
comment
Может быть ваша форма события mousemove зарегистрирует этот метод ?!   -  person Reza ArabQaeni    schedule 13.12.2011
comment
Непрерывно, как в течение всего времени, в течение которого он работает, или только в течение определенного периода времени? События беспорядочные? (Если это так, подозревайте вибрацию и чрезмерно чувствительную мышь.)   -  person Ry-♦    schedule 13.12.2011
comment
Вы можете попробовать запустить Spy ++ и отслеживать сообщения Windows, чтобы попытаться увидеть, что еще происходит. Если у вас Visual Studio, в одной из папок инструментов должен быть spyxx.exe. Кроме того, попробуйте физически отключить мышь во время отладки и посмотрите, все ли вы получаете сообщения MouseMove.   -  person Trevor Elliott    schedule 13.12.2011
comment
У меня есть возможность запустить те же коды на другом ПК, и он не может быть воспроизведен. Что-то должно быть не так с первым ПК. Я попробую использовать Spy ++, как предлагал Мохзе. Спасибо!   -  person Setyo N    schedule 13.12.2011
comment
наклонный стол? напомни мне никогда не играть против тебя в покер :)   -  person Jeremy Thompson    schedule 13.12.2011


Ответы (4)


Первое предположение ... либо сейсмическая активность, либо нарглс - подозреваю, нарглс :).

Используя предоставленный вами образец кода, я не получаю такого же поведения. Мой ярлык обновляется, только если мышь действительно движется. (и для загрузки указатель должен находиться над окном изображения).

А если серьезно ... на вашем столе есть какие-то вибрации? Я мог бы также попробовать другую мышь - так как схема внутри может отправлять неверные данные.

person RThomas    schedule 12.12.2011
comment
Нет, я удостоверяюсь, что положение мыши не меняется, показывая e.X и e.Y на этикетке, но, как ни странно, информация о времени на этикетке изменяется со скоростью, например, один раз в секунду. Дополнительная информация: использование VS 2008 SP1 на Vista SP2. Может быть, это ошибка Windows / VS / .NET на моем ПК? - person Setyo N; 13.12.2011

Некоторые методы, использующие формы окна, вызывают некоторый уровень внутреннего обновления формы, что (по моей оценке) заставляет форму «подбирать» позицию мыши и, таким образом, запускать событие MouseMove. Один из таких методов - связать всплывающую подсказку с формой. Как результат,

int moveCount = 0;
ToolTip toolTip = new ToolTip();
private void form1_MouseMove(object sender, MouseEventArgs e)
{
    Trace.WriteLine(moveCount);
    moveCount++;
    toolTip.SetToolTip(this, "Hello world");
}

будет срабатывать постоянно, даже если мышь не перемещается, в то время как

int moveCount = 0;
private void form1_MouseMove(object sender, MouseEventArgs e)
{
    Trace.WriteLine(moveCount);
    moveCount++;
}

срабатывает только тогда, когда мышь действительно перемещается.

Заглянув внутрь события MouseMove на предмет чего-то, что «глубоко» касается формы, может помочь выявить источник поведения цикла.

person NiloCK    schedule 20.12.2013

«pictureBox1_MouseMove» - это просто функция-делегат. Таким образом, с вашим кодом мы можем только предположить, что он был прикреплен к MouseMove и только MouseMove в дизайнере.

Дважды проверьте все ссылки на «pictureBox1_MouseMove», а также имейте в виду, что Windows запускает сообщения MouseMove при щелчке мыши, даже если вы не двигаете мышь.

В худшем случае вы можете сохранить точку e.Location в локальной переменной-члене ("oldLocation") и убедиться, что мышь действительно перемещается перед обработкой вашей команды:

private Point oldLocation = Point.Empty;

private void pictureBox1_MouseMove ( object sender, MouseEventArgs e )
{
    if (e.Location != oldLocation)
    {
        oldLocation = e.Location;

        label1.Text = DateTime.Now.ToLongTimeString ( ) + ": " + e.X + "," + e.Y;
    }
}
person Trevor Elliott    schedule 12.12.2011
comment
Думаю, вы тоже можете сократить его до e.Location != oldLocation. - person Ry-♦; 13.12.2011
comment
+1 хороший звонок, чтобы убедиться, что делегат подключен к нужному мероприятию. - person RThomas; 13.12.2011

Наблюдение: если код обработчика события MouseMove изменяет размер элемента управления (явно или неявно в соответствии со свойством AutoSize) в любом направлении, обработчик события MouseMove будет повторно вызван, несмотря на отсутствие фактического движения мыши. Это может привести к возникновению порочного круга. Если ширина элемента управления с автоматическим изменением размера остается стабильной, несмотря на изменение его содержимого, обработчик MouseEvent не будет повторно вызван.

person Christopher Smith    schedule 20.04.2020