Winform中实现无边框窗体只需要设置一个属性FormBorderStyle = FormBorderStyle.None;即可,或者在设计器中直接设置。无边框表单的结果是丢失了标题栏和控制框(最小化、最大值和关闭按钮)。如果没有标题栏,则无法拖动和移动窗口。如果没有边框,则无法拖动 Windows 边缘来调整其大小。移动表单非常简单,但边缘拖动调整大小有点棘手。
下面通过监听鼠标事件和调整光标形状,实现了一个用户可以通过拖拽窗体边缘来调整窗体大小的功能。同时,它还确保了当鼠标离开窗体时,光标形状会恢复为默认的箭头形状。
先上效果图
![](https://pic.rmb.bdstatic.com/bjh/3ead987300/240927/4ca3a4f4ce69880aad7b5555eadae55a.gif)
具体来说,它允许用户通过拖动鼠标来改变窗体的大小。以下是代码的工作原理概述:
1.初始化:
在构造函数 Form1() 中,为 Form1 实例注册了两个事件处理器:MouseMove 用于处理鼠标移动时的行为,MouseLeave 用于处理鼠标离开窗体时的行为。
2.鼠标移动处理 (Main_MouseMove):
如果鼠标接近右下角,则显示双向对角线箭头。
如果鼠标接近右侧,则显示水平箭头。
如果鼠标接近底部,则显示垂直箭头。
Cursors.SizeNWSE: 允许同时改变窗体的宽度和高度。
Cursors.SizeWE: 只允许改变窗体的宽度。
Cursors.SizeNS: 只允许改变窗体的高度。
当鼠标在窗体内移动时,会触发 MouseMove 事件。
如果鼠标左键被按下,并且光标形状是某种尺寸调整箭头(Cursors.SizeNWSE, Cursors.SizeWE, 或 Cursors.SizeNS),则根据当前光标类型调整窗体的宽度和/或高度。
根据鼠标位置与窗体边缘的距离(5像素内),动态地改变光标形状以提示用户可以进行何种类型的尺寸调整:
如果鼠标不在这些区域,则恢复默认的箭头光标。
3.鼠标离开窗体处理 (Main_Leave):
当鼠标指针离开窗体范围时,将光标恢复到默认的箭头状态。
完整代码如下
namespace test2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MouseMove += Main_MouseMove;
MouseLeave += Main_Leave; // 有控件在边缘时,处理一下更好一些
}
#region 拖拽调整窗体大小
private void Main_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)//左键按下移动,拖拽调整大小
{
// MousePosition的参考点是屏幕的左上角,表示鼠标当前相对于屏幕左上角的坐标。this.Left和this.Top的参考点也是屏幕
if (Cursor == Cursors.SizeNWSE) // 倾斜拖拽
{
// 改变窗体宽和高的代码,其宽高为鼠标屏幕位置减去窗体的Left,Top距离
this.Width = MousePosition.X - this.Left;
this.Height = MousePosition.Y - this.Top;
}
else if (Cursor == Cursors.SizeWE) // 水平拖拽
{
Width = MousePosition.X - this.Left;
}
else if (Cursor == Cursors.SizeNS) // 垂直拖拽
{
Height = MousePosition.Y - this.Top;
}
}
//鼠标移动过程中,坐标时刻在改变
//当鼠标移动时横坐标距离窗体右边缘5像素以内且纵坐标距离下边缘也在5像素以内时,要将光标变为倾斜的箭头形状
if (e.Location.X >= this.Width - 5 && e.Location.Y > this.Height - 5)
{
this.Cursor = Cursors.SizeNWSE; // 右下角 双向对角线光标
}
//当鼠标移动时横坐标距离窗体右边缘5像素以内时,要将光标变为双向水平箭头形状
else if (e.Location.X >= this.Width - 5)
{
this.Cursor = Cursors.SizeWE; // 双向水平光标
}
//当鼠标移动时纵坐标距离窗体下边缘5像素以内时,要将光标变为垂直水平箭头形状
else if (e.Location.Y >= this.Height - 5)
{
this.Cursor = Cursors.SizeNS; // 双向垂直光标
}
//否则,以外的窗体区域,鼠标星座均为单向箭头(默认)
else this.Cursor = Cursors.Arrow;
}
private void Main_Leave(object sender, EventArgs e)
{
Cursor = Cursors.Arrow;// 移出窗体变为正常
}
#endregion
}
}
通过这种方式,当用户将鼠标悬停在窗体边缘并拖动时,窗体会相应地改变其大小,提供了直观的用户体验。这段代码没有涉及到实际的拖动整个窗体的位置,仅关注于改变窗体的尺寸。如果需要实现窗体位置的拖动,还需要额外的逻辑来处理标题栏或其他指定区域的拖动行为。