locked
Can only call DragMove when primary mouse button is down. RRS feed

  • Question

  • I need a control on which I will fire MouseLeftButton down, which will invoke DraMove() on a window in which the control resides.

     

    var testWindow = new Window (); 

    int timestamp = new TimeSpan(DateTime.Now.Ticks).Milliseconds;

    const MouseButton mouseButton = MouseButton.Left;

    var mouseDownEvent =

                   new MouseButtonEventArgs(System.Windows.Input.Mouse.PrimaryDevice, timestamp, mouseButton) {

                       RoutedEvent = UIElement.MouseLeftButtonDownEvent,

                       Source = testWindow,

                   };

     

    testWindow.RaiseEvent(mouseDownEvent);

     

    This is the test code the raises the left mouse button down event on the window.

     

    In the handler of that event is called

     

                   var window = Window.GetWindow(element);

                    if (window != null) {

                         window.DragMove();                   

                    }

     

    The DragMove() raises an exception “Can only call DragMove when primary mouse button is down"

     

    How can I raise the LeftMouseButton event differently? Or can I make the primary mouse button pressed?

     

    Thanks

    Friday, December 16, 2011 11:57 AM

Answers

  • You have to press the left button then you can call the Window.DragMove() method. Reflected code:

    public void DragMove()
    {
        this.VerifyApiSupported();
        SecurityHelper.DemandUIWindowPermission();
        this.VerifyContextAndObjectState();
        this.VerifyHwndCreateShowState();
        if (!this.IsSourceWindowNull && !this.IsCompositionTargetInvalid)
        {
            if (Mouse.LeftButton != MouseButtonState.Pressed)
            {
                throw new InvalidOperationException(SR.Get("DragMoveFail"));
            }
            if (this.WindowState == WindowState.Normal)
            {
                UnsafeNativeMethods.SendMessage(this.CriticalHandle, WindowMessage.WM_SYSCOMMAND, (IntPtr) 0xf012, IntPtr.Zero);
                UnsafeNativeMethods.SendMessage(this.CriticalHandle, WindowMessage.WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
            }
        }
    }
    
    


    So you could design your own DragMove method similar with the code from Window class, and do not check the LeftButton  status. But we do not recommend you to SendMessage without the checking. But you could try it and test if it can work.

    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us


    • Edited by Jie Bao Monday, December 26, 2011 5:10 AM
    • Marked as answer by Min Zhu Monday, January 2, 2012 1:57 AM
    Wednesday, December 21, 2011 10:28 AM

All replies

  • May be you can try PreviewMouseLeftButtonDown

                int timestamp = new TimeSpan(DateTime.Now.Ticks).Milliseconds;
                const MouseButton mouseButton = MouseButton.Left;
                var mouseDownEvent =
                               new MouseButtonEventArgs(System.Windows.Input.Mouse.PrimaryDevice, timestamp, mouseButton)
                               {
                                   RoutedEvent = UIElement.PreviewMouseLeftButtonDownEvent,
                                   Source = testWindow,
                               };
    
                testWindow.RaiseEvent(mouseDownEvent);
    



    Gaurav Khanna | Microsoft VB.NET MVP
    Friday, December 16, 2011 6:28 PM
  • thanks for the answer, but it didn't help.

    The DragMove still raises the same exception  “Can only call DragMove when primary mouse button is down".

    Monday, December 19, 2011 10:54 AM
  • You have to press the left button then you can call the Window.DragMove() method. Reflected code:

    public void DragMove()
    {
        this.VerifyApiSupported();
        SecurityHelper.DemandUIWindowPermission();
        this.VerifyContextAndObjectState();
        this.VerifyHwndCreateShowState();
        if (!this.IsSourceWindowNull && !this.IsCompositionTargetInvalid)
        {
            if (Mouse.LeftButton != MouseButtonState.Pressed)
            {
                throw new InvalidOperationException(SR.Get("DragMoveFail"));
            }
            if (this.WindowState == WindowState.Normal)
            {
                UnsafeNativeMethods.SendMessage(this.CriticalHandle, WindowMessage.WM_SYSCOMMAND, (IntPtr) 0xf012, IntPtr.Zero);
                UnsafeNativeMethods.SendMessage(this.CriticalHandle, WindowMessage.WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
            }
        }
    }
    
    


    So you could design your own DragMove method similar with the code from Window class, and do not check the LeftButton  status. But we do not recommend you to SendMessage without the checking. But you could try it and test if it can work.

    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us


    • Edited by Jie Bao Monday, December 26, 2011 5:10 AM
    • Marked as answer by Min Zhu Monday, January 2, 2012 1:57 AM
    Wednesday, December 21, 2011 10:28 AM
  • How can I simulate that the Mouse.LeftButton state is pressed (MouseButtonState.Pressed)?


    Thursday, December 22, 2011 9:50 AM
  • No, you cannot simulate the status, since it is a readonly property in the Mouse device. You have to press the Button. 
    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Thursday, December 22, 2011 10:00 AM
  • So for automated unit test I can not simulate from code firing of the MouseLeftButton down, which will invoke DragMove() on a window. The DragMove() expects the pressed state of the  MouseLeftButton.   
    Thursday, December 22, 2011 12:37 PM
  • Yes, that is the key we cannot simulate the DragMove from code. .Net Framework check the ButtonStatus, and shit status can only be set by the device in system. It cannot be set via code.


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    • Edited by Jie Bao Monday, December 26, 2011 5:11 AM
    Monday, December 26, 2011 5:10 AM