通过鼠标拖动移动无框Windows窗体

时间:2014-03-11 06:42:42

标签: c# winforms

我是C#的新手,我在StackExchange上尝试过很多解决方案而且我没有运气试图设置一个控件或整个表单来左键单击并拖动整个窗口。我正在使用visual studio 12中的无框窗口。我最接近移动窗口的是移动一个带有pastebin组件的控件(最后一个响应) - How do I make mousedrag inside Panel move form window? 我只能让面板本身与该组件一起移动。

我尝试了大多数方法,但我似乎迷失了,我根据自己的需要定制它。我尝试过WndProc覆盖,但是当我试图移动窗体窗口时,它没有做任何事情。

我有两个面板,我希望能够使用DragPanel和DragPanel2拖动窗口。

这是我最近尝试使用整个表单的失败方法。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
        InsideMover _dragger = new InsideMover();
        _dragger.ControlToMove = this.DragPanel;
    }

    private void close_Click(object sender, EventArgs e)
    {
        Close();
    }
}

public class InsideMover : Component
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private Container components = null;

    public InsideMover(IContainer container)
    {
        ///
        /// Required for Windows.Forms Class Composition Designer support
        ///
        container.Add(this);
        InitializeComponent();

        //
        // TODO: Add any constructor code after InitializeComponent call
        //
    }

    public InsideMover()
    {
        ///
        /// Required for Windows.Forms Class Composition Designer support
        ///
        InitializeComponent();

        //
        // TODO: Add any constructor code after InitializeComponent call
        //
    }

    public Control ControlToMove
    {
        set
        {
            if (_parent != null)
            {
                //  odkvaci prijasnje evente
                _parent.MouseDown -= new MouseEventHandler(_parent_MouseDown);
                _parent.MouseMove -= new MouseEventHandler(_parent_MouseMove);
                _parent.MouseUp -= new MouseEventHandler(_parent_MouseUp);
                _parent.DoubleClick -= new EventHandler(_parent_DoubleClick);
            }
            _parent = value;
            if (value != null)
            {
                //  zakači se na evente od containera koji ti trebaju
                _parent.MouseDown += new MouseEventHandler(_parent_MouseDown);
                _parent.MouseMove += new MouseEventHandler(_parent_MouseMove);
                _parent.MouseUp += new MouseEventHandler(_parent_MouseUp);
                _parent.DoubleClick += new EventHandler(_parent_DoubleClick);
            }
        }
        get
        {
            return _parent;
        }
    }

    Control _parent;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (components != null)
            {
                components.Dispose();
            }
        }
        base.Dispose(disposing);
    }


    #region Component Designer generated code
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        components = new System.ComponentModel.Container();
    }
    #endregion

    int _lastMouseX;
    int _lastMouseY;
    bool _moving;

    public void StartMouseDown(MouseEventArgs e)
    {
        _parent_MouseDown(null, e);
    }

    private void _parent_MouseDown(object sender, MouseEventArgs e)
    {
        _lastMouseX = e.X;
        _lastMouseY = e.Y;
        _moving = true;
    }

    private void _parent_MouseMove(object sender, MouseEventArgs e)
    {
        if (_moving)
        {
            Point newLocation = _parent.Location;
            newLocation.X += e.X - _lastMouseX;
            newLocation.Y += e.Y - _lastMouseY;
            _parent.Location = newLocation;
        }
    }

    private void _parent_MouseUp(object sender, MouseEventArgs e)
    {
        _moving = false;
    }

    private void _parent_DoubleClick(object sender, EventArgs e)
    {
        if (_parent is Form)
        {
            Form f = (Form)_parent;
            if (f.WindowState == FormWindowState.Normal)
            {
                f.WindowState = FormWindowState.Maximized;
            }
            else
            {
                f.WindowState = FormWindowState.Normal;
            }
        }
    }
}
}

如何将面板设置为左键单击拖动窗口?

我在上面的帖子和WndProc方法中尝试了所有方法: Drag borderless windows form by mouse

1 个答案:

答案 0 :(得分:0)

如果你按照你发布的链接中的答案,它正在使用mousemove事件,而根据你发布的代码判断,你正在使用mousedown事件。鼠标按下事件仅在您按下鼠标按钮时调用一次,如果在按住按钮的同时移动鼠标,则不会再次调用它。而只要指针移动,就会调用mousemove事件。因此,最好的办法是用mousemove事件改变你的mousedown事件,即

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
   if (e.Button == MouseButtons.Left)
   {
      ReleaseCapture();
      SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
   }
}

如果这不起作用,你可以在mousemove事件中做这样的事情,首先在表格中创建一个Point'prevpoint'和一个偏移点。

Point prevpoint=new Point(0,0);
Point offset=new Point(0,0);
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
   if (e.Button == MouseButtons.Left)
   {
      offset.X=e.X-prevpoint.X;
      offset.Y=e.Y-prevpoint.Y;
      prevpoint.X=e.X;
      prevpoint.Y=e.Y;
      this.Location = new Point(this.Location.X + offset.X, this.Location.Y + offset.Y);
   }
}

我没有测试过上面的代码,但希望能给你一个基本的想法。