1. 设置无边框模式
选中要去除边框的窗体,按F4调出其属性面板,在属性面板中找到 FormBorderStyle ,并选择 None,即可将窗体设置成无边框模式;默认是无法随意拖动的,也没有最大化最小化关闭按钮。
2. 通过Panel控件实现窗体移动
实现方法 :在窗体的头部添加 Panel 控件,通过 Panel 的 MouseDown、MouseMove 事件实现窗体移动;(这里的话可以添加一个背景色更好)
实现原理: 直接通过修改窗体位置从而达到移动窗体的效果;
代码实现:
//定义一个位置信息Point用于存储鼠标位置
private Point mpoint;
/// <summary>
/// 鼠标移动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void panel1_MouseMove(object sender, MouseEventArgs e)
{if (e.Button == MouseButtons.Left){this.Location = new Point(this.Location.X + e.X - mpoint.X, this.Location.Y + e.Y - mpoint.Y);}
}
/// <summary>
/// 鼠标按下事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void panel1_MouseDown(object sender, MouseEventArgs e)
{mpoint = new Point(e.X, e.Y);
}
3. 通过窗体事件实现窗体移动
实现方法:通过窗体MouseDown、MouseMove、MouseUp事件实现窗体移动;
代码演示:
//定义一个位置信息Point用于存储鼠标位置
private Point mpoint;
// 定义一个bool变量用于判断鼠标是否按下
private bool isMouseDown = false;/// <summary>
/// 鼠标释放事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_MouseDown(object sender, MouseEventArgs e)
{// 鼠标左键按下mpoint = e.Location;// 记录鼠标按下状态if (e.Button == MouseButtons.Left){isMouseDown = true;}
}
/// <summary>
/// 鼠标移动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_MouseMove(object sender, MouseEventArgs e)
{if(e.Button == MouseButtons.Left && isMouseDown){Location += new Size(e.Location.X - mpoint.X, e.Location.Y - mpoint.Y);}
}
/// <summary>
/// 鼠标释放事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_MouseUp(object sender, MouseEventArgs e)
{isMouseDown = false; // 鼠标左键释放
}
3.1. 前提准备
private Point mpoint; // 用来记住“鼠标刚按下去时,在窗体内的位置”
private bool isMouseDown = false; // 标记“鼠标是不是正按着”
比如你点在窗体标题栏(或任意位置)的 (50, 30) 处,mpoint
就记下这个点。
3.2. 1️⃣ 鼠标按下时(MouseDown
)
private void Form1_MouseDown(object sender, MouseEventArgs e)
{mpoint = e.Location; // 记录:鼠标在窗体内的坐标(比如 (50,30))if (e.Button == MouseButtons.Left){isMouseDown = true; // 标记:现在鼠标左键按下了}
}
✅ 作用:
- 记住你“从哪里开始拖”
- 告诉程序:“我要开始拖窗体了!”
3.3. 2️⃣ 鼠标移动时(MouseMove
)
private void Form1_MouseMove(object sender, MouseEventArgs e)
{if (e.Button == MouseButtons.Left && isMouseDown){Location += new Size(e.Location.X - mpoint.X, e.Location.Y - mpoint.Y);}
}
关键逻辑拆解:
-
e.Location
:当前鼠标在窗体内部的坐标(比如现在移到了 (60, 40)) -
mpoint
:最初按下的位置(比如 (50, 30)) -
e.Location - mpoint
= (10, 10) → 表示鼠标相对于按下点,移动了多少
于是:
Location += new Size(10, 10);
就是把整个窗体的位置向右下移动 10 像素。
每次鼠标一动,就计算“偏移量”,然后让窗体跟着偏移 —— 看起来就像你拖着窗体走!
为什么用 Location += ...
?
因为 Location
是窗体左上角在屏幕上的坐标。加一个偏移量,窗体就跟着动。
3.4. 3️⃣ 鼠标松开时(MouseUp
)
private void Form1_MouseUp(object sender, MouseEventArgs e)
{isMouseDown = false; // 标记:鼠标松开了,停止拖拽
}
✅ 作用:
- 告诉程序:“我不拖了!”
- 下次再移动鼠标,
MouseMove
里的if
条件不成立,窗体就不会乱跑了
3.5. 整体流程(举个栗子)
- 你在窗体上 (50, 30) 处按下鼠标左键
→mpoint = (50, 30)
,isMouseDown = true
- 你把鼠标拖到 (80, 60)
→e.Location = (80, 60)
→ 偏移量 = (80-50, 60-30) = (30, 30)
→Location += (30, 30)
→ 窗体整体右移 30、下移 30 - 你松开鼠标
→isMouseDown = false
→ 再移动鼠标,窗体不动了
3.6. ⚠️ 注意事项
- 这段代码通常用在 无边框窗体(
FormBorderStyle = None
)上,因为默认窗体可以拖标题栏移动,不需要自己实现。 - 如果窗体有标题栏,这样写会导致“点哪都能拖”,可能不符合用户习惯。
-
Location
改变的是窗体在屏幕上的绝对位置,不是相对位置。
3.7. ✅ 总结一句话:
这段代码实现了 “鼠标按住窗体任意位置拖动,窗体跟着走” 的功能,核心是:
记录起点 → 计算偏移 → 移动窗体 → 松手停止。