無標題列視窗 (FormBorderStyle.None) 或任意控制項 (如 Panel、Label) 捕捉滑鼠拖曳以移動整個視窗。
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Yoker.FormUtils
{
public class DragFormClass
{
private static bool _isMouseDown;
private static Point _mouseOffset;
private static Form _form;
public static void BindControl(Control control)
{
if (control == null) return;
_form = control.FindForm();
control.MouseDown += Control_MouseDown;
control.MouseMove += Control_MouseMove;
control.MouseUp += Control_MouseUp;
}
private static void Control_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
var ctrl = (Control)sender;
int offsetX = -e.X;
int offsetY = -e.Y;
// 若非 Form 本身,需加上控制項在 Form 中的位置
if (!(ctrl is Form))
{
offsetX -= ctrl.Left;
offsetY -= ctrl.Top;
}
// 若 Form 有邊框/標題列,需扣除系統邊框與標題列高度
if (_form.FormBorderStyle != FormBorderStyle.None)
{
offsetX -= SystemInformation.FrameBorderSize.Width;
offsetY -= SystemInformation.FrameBorderSize.Height + SystemInformation.CaptionHeight;
}
_mouseOffset = new Point(offsetX, offsetY);
_isMouseDown = true;
}
private static void Control_MouseMove(object sender, MouseEventArgs e)
{
if (!_isMouseDown) return;
Point mousePos = Control.MousePosition;
mousePos.Offset(_mouseOffset.X, _mouseOffset.Y);
_form.Location = mousePos;
}
private static void Control_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
_isMouseDown = false;
}
}
}
// 在 Form_Load 或建構函式中
DragFormClass.BindControl(this); // 整個表單可拖曳 (適用無標題列)
// 或
DragFormClass.BindControl(panelTitleBar); // 僅標題列 Panel 可拖曳
// 或
DragFormClass.BindControl(labelTitle); // 單一 Label 可拖曳
MouseDown:計算滑鼠相對視窗左上角的偏移量,考慮控制項位置與系統邊框/標題列。MouseMove:以螢幕座標 Control.MousePosition 加上偏移量,直接設定 Form.Location。MouseUp:重置旗標。