Drag a WPF Form around the desktop

左心房为你撑大大i 提交于 2019-12-04 00:50:00

You can use the Window.DragMove method in the mouse down event of the window.

Previous answers hit on the answer, but the full example is this:

   private void Window_MouseDown(object sender, MouseButtonEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            DragMove();
        }
    }

Here is some simplified code to drag the WPF form around your screen. You might have seen some of this code on different posts, I just modified it to fit the needs of dragging the WPF form.

Keep in mind we need to grab the form position on the MouseLeftButtonDown, so we can keep the mouse pointer positioned in the same spot on the form as we are dragging it around the screen.

You will also need to add the following reference to get the mouse position relative to the screen: System.Windows.Forms

Properties Needed:

private bool _IsDragInProgress { get; set; }
private System.Windows.Point _FormMousePosition {get;set;}

Code:

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            this._IsDragInProgress = true;
            this.CaptureMouse();
            this._FormMousePosition = e.GetPosition((UIElement)this);
            base.OnMouseLeftButtonDown(e);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (!this._IsDragInProgress)
                return;

            System.Drawing.Point screenPos = (System.Drawing.Point)System.Windows.Forms.Cursor.Position;
            double top = (double)screenPos.Y - (double)this._FormMousePosition.Y;
            double left = (double)screenPos.X - (double)this._FormMousePosition.X;
            this.SetValue(MainWindow.TopProperty, top);
            this.SetValue(MainWindow.LeftProperty, left);
            base.OnMouseMove(e);
        }

        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            this._IsDragInProgress = false;
            this.ReleaseMouseCapture();
            base.OnMouseLeftButtonUp(e);
        }
HelloSam

If you, like me, want to have a little bit more control about the DoDragMove() - says, to have the window always stay in the border of the current desktop, I have made this.

Usage:

public partial class MainWindow : Window
{
    private WindowsDragger _dragger;

    public MainWindow()
    {
        InitializeComponent();
        _dragger = new WindowsDragger(this);
    }
}

Helper Class:

class WindowsDragger
{
    private readonly Window _window;
    private Point _dragDelta;

    public WindowsDragger(Window window)
    {
        _window = window;

        _window.MouseLeftButtonDown += MouseLeftButtonDown;
        _window.MouseLeftButtonUp += MouseLeftButtonUp;
        _window.MouseMove += MouseMove;
    }

    void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        _dragDelta = e.GetPosition(_window);
        Mouse.Capture(_window);
    }

    void MouseMove(object sender, MouseEventArgs e)
    {
        if (Equals(_window, Mouse.Captured))
        {
            var pos = _window.PointToScreen(e.GetPosition(_window));
            var verifiedPos = CoerceWindowBound(pos - _dragDelta);
            _window.Left = verifiedPos.X;
            _window.Top = verifiedPos.Y;
        }
    }

    void MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (Equals(_window, Mouse.Captured))
            Mouse.Capture(null);
    }

    private Vector CoerceWindowBound(Vector newPoint)
    {
        // Snap to the current desktop border
        var screen = WpfScreen.GetScreenFrom(_window);
        var wa = screen.WorkingArea;
        if (newPoint.X < wa.Top) newPoint.X = wa.Top;
        if (newPoint.Y < wa.Left) newPoint.Y = wa.Left;
        if (_window.Width + newPoint.X > wa.Right) newPoint.X = wa.Right - _window.Width;
        if (_window.Height + newPoint.Y > wa.Bottom) newPoint.Y = wa.Bottom - _window.Height;
        return newPoint;
    }
}

where WpfScreen is from here: How to get the size of the current screen in WPF?

on windows load or the grid load event you can use a delegate to trigger the DragMove() function.

`private void Grid_Loaded(object sender, RoutedEventArgs e) {

        this.MouseDown += delegate{DragMove();};

    }`
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!