dotnet/wpf · error · InvalidOperationException

SR.DragMoveFail

Error message

SR.DragMoveFail

What it means

Window.DragMove initiates a mouse-drag window move by sending WM_SYSCOMMAND/SC_MOUSEMOVE, which is only valid while the left mouse button is down. If DragMove is called when the mouse's left button is not pressed (or outside a valid drag context), WPF throws this InvalidOperationException (SR.DragMoveFail).

Solutions

  1. Call DragMove only inside a MouseLeftButtonDown event handler, synchronously
  2. Do not defer the call with Dispatcher.BeginInvoke or async continuations
  3. Verify Mouse.LeftButton == MouseButtonState.Pressed before calling DragMove
  4. For button-click initiated drags, capture mouse on down and call DragMove on the down event instead

Example fix

// before
private void TitleBar_Click(object sender, RoutedEventArgs e) {
    DragMove(); // throws: left button not down
}
// after
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
    if (Mouse.LeftButton == MouseButtonState.Pressed) {
        DragMove();
    }
}
Defensive patterns

Strategy: validation

Validate before calling

if (e is MouseButtonEventArgs mbe && mbe.ChangedButton == MouseButton.Left && Mouse.LeftButton == MouseButtonState.Pressed) { DragMove(); }

Type guard

bool CanDragMove() => Mouse.LeftButton == MouseButtonState.Pressed;

Try / catch

try { DragMove(); } catch (InvalidOperationException ex) when (ex.Message == SR.DragMoveFail) { /* ignore: not in drag state */ }

Prevention

When it happens

Trigger: Calling window.DragMove() outside of a MouseLeftButtonDown handler (e.g. from a Click event, a timer, or before the left button is pressed), or calling it after the mouse-up already occurred.

Common situations: Implementing custom chrome/borderless windows and wiring DragMove to MouseLeftButtonUp or a button click instead of MouseLeftButtonDown; calling DragMove asynchronously (Dispatcher.BeginInvoke) after the button state changed; simulating drag on touch without mouse capture.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/5a5d5d551548e4ca. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs:257

                return;
            }

            // Mouse.LeftButton actually reflects the primary button user is using.
            // So we don't need to check whether the button has been swapped here.
            if (Mouse.LeftButton == MouseButtonState.Pressed)
            {
                if (WindowState == WindowState.Normal)
                {
                    // SendMessage's return value is dependent on the message send.  WM_SYSCOMMAND
                    // and WM_LBUTTONUP return value just signify whether the WndProc handled the
                    // message or not, so they are not interesting
                    UnsafeNativeMethods.SendMessage( Handle, WindowMessage.WM_SYSCOMMAND, (IntPtr)NativeMethods.SC_MOUSEMOVE, IntPtr.Zero);
                    UnsafeNativeMethods.SendMessage( Handle, WindowMessage.WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
                }
            }
            else
            {
                throw new InvalidOperationException(SR.DragMoveFail);
            }
}

        /// <summary>
        ///     Shows the window as a modal window
        /// </summary>
        /// <returns>bool?</returns>
        /// <remarks>
        ///     Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API.
        /// </remarks>
        public Nullable<bool> ShowDialog()
        {
            // this call ends up throwing an exception if ShowDialog
            // is not allowed
            VerifyApiSupported();
            VerifyContextAndObjectState();
            VerifyCanShow();
            VerifyNotClosing();

View on GitHub (pinned to 81131a70a4)