none
重写Button.OnMouseMove方法的问题 RRS feed

  • 问题

  • 在Button的子类中重写了OnMouseMove方法,代码如下:

    public class MyButton : Button
        {
            protected override void OnMouseMove(MouseEventArgs e)
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    MessageBox.Show("mouseMoving");
                }
            }
    
            //protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
            //{  }
    
        }

    在此按钮上按住鼠标左键移动时, MessageBox.Show("mouseMoving")会执行两次,

    如果把重写的OnMouseLeftButtonDown方法(空方法,什么都不做)的注释取消,MessageBox.Show("mouseMoving")就只执行一次,这是什么原因?

    2014年2月20日 9:44

答案

  • 在鼠标按下后,先会执行OnMouseDown,然后是OnMouseLeftButtonDown,然后是OnMouseMove,而在你的OnMouseMove代码中弹出了消息框,此时按钮会失去焦点和失去对鼠标的捕获,此时会执行OnMouseMove然后是OnMouseLeave,在这个过程中,OnMouseMove被执行了两次,所以你会看到两次消息框。

    总而言之,OnMouseMove并非只有鼠标移动时才会执行。

    • 已标记为答案 seewold 2014年2月26日 7:53
    2014年2月21日 8:41

全部回复

  • Hi, 如果去掉注释,以下代码其实是把OnMouseLeftButtonDown重写了,在基类的OnMouseLeftButtonDown方法里,是有后续处理(设置状态、引发事件等等)的,如果改成以下代码,相当于把后续处理去掉了,当然会看到和注释掉时不一样的情形。

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    { 
    }

    你可以试一下把代码改成这样

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
         base.OnMouseLeftButtonDown(e);
    }
    就会发现无论是否注释掉,程序的表现都一样。

    2014年2月20日 11:31
  • 谢谢的解答。确实,在OnMouseLeftButtonDown中加上   base.OnMouseLeftButtonDown(e) 后,程序的表现是一样了

    可是还是有个疑问:我只单击MyButton ,并不移动鼠标,OnMouseMove中的 MessageBox.Show("mouseMoving")也会执行两次,为什么呢?

    2014年2月21日 7:14
  • 在鼠标按下后,先会执行OnMouseDown,然后是OnMouseLeftButtonDown,然后是OnMouseMove,而在你的OnMouseMove代码中弹出了消息框,此时按钮会失去焦点和失去对鼠标的捕获,此时会执行OnMouseMove然后是OnMouseLeave,在这个过程中,OnMouseMove被执行了两次,所以你会看到两次消息框。

    总而言之,OnMouseMove并非只有鼠标移动时才会执行。

    • 已标记为答案 seewold 2014年2月26日 7:53
    2014年2月21日 8:41
  • 明白了,多谢指教!

    2014年2月26日 7:51