前言
用户界面的美观性和个性化程度越来越受到重视。传统的矩形窗体已无法满足某些特定项目对视觉效果的需求。使用 C# 和 GDI+ 技术,我们可以轻松实现自定义窗体样式,其中 圆角窗体(Rounded Form) 是一个经典且实用的案例。
本文将从原理讲解到代码实现,全面介绍如何使用 C# 的 GDI+ 绘图技术打造一个支持圆角、边框、背景色、拖动功能以及阴影效果的 WinForms 自定义窗体,并提供完整的代码示例与使用注意事项。
正文
一、实现原理
圆角窗体的核心在于对窗体外观的完全自定义绘制。其实现主要依赖以下关键技术点:
1、GraphicsPath 创建圆角路径:用于定义窗体的形状。
2、Region 设置窗体区域:通过设置窗体的 Region 属性,使其显示为圆角形状。
3、重写 OnPaint 方法:实现自定义绘图逻辑,包括背景填充和边框绘制。
4、实现窗体拖动功能:通过鼠标事件控制窗体移动。
5、添加阴影效果:利用 Windows API 实现窗体阴影。
二、完整代码实现
1、创建基础窗体类
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
public class RoundedForm : Form
{
// 圆角半径
private int cornerRadius = 20;
// 窗体边框颜色
private Color borderColor = Color.FromArgb(100, 100, 100);
// 窗体背景色
private Color backgroundColor = Color.White;
public RoundedForm()
{
// 设置窗体基本属性
this.FormBorderStyle = FormBorderStyle.None;
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
this.Size = new Size(800, 500);
}
// 属性:圆角半径
public int CornerRadius
{
get { return cornerRadius; }
set
{
cornerRadius = value;
this.Invalidate();
}
}
// 属性:边框颜色
public Color BorderColor
{
get { return borderColor; }
set
{
borderColor = value;
this.Invalidate();
}
}
// 属性:背景颜色
public Color BackgroundColor
{
get { return backgroundColor; }
set
{
backgroundColor = value;
this.Invalidate();
}
}
}
2、实现圆角路径创建方法
private GraphicsPath CreateRoundedPath(Rectangle rect, int radius)
{
GraphicsPath path = new GraphicsPath();
radius = Math.Min(radius, Math.Min(rect.Width / 2, rect.Height / 2));
int diameter = radius * 2;
Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter));
// 左上角
path.AddArc(arcRect.X, arcRect.Y, diameter, diameter, 180, 90);
// 右上角
arcRect.X = rect.Right - diameter;
path.AddArc(arcRect.X, arcRect.Y, diameter, diameter, 270, 90);
// 右下角
arcRect.Y = rect.Bottom - diameter;
path.AddArc(arcRect.X, arcRect.Y, diameter, diameter, 0, 90);
// 左下角
arcRect.X = rect.Left;
path.AddArc(arcRect.X, arcRect.Y, diameter, diameter, 90, 90);
path.CloseFigure();
return path;
}
3、重写 OnPaint 方法实现自定义绘制
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.CompositingQuality = CompositingQuality.HighQuality;
Rectangle rect = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
using (GraphicsPath path = CreateRoundedPath(rect, cornerRadius))
{
this.Region = new Region(path);
using (SolidBrush brush = new SolidBrush(backgroundColor))
{
g.FillPath(brush, path);
}
using (Pen pen = new Pen(borderColor, 1.0f))
{
pen.Alignment = PenAlignment.Inset;
pen.EndCap = LineCap.Round;
pen.StartCap = LineCap.Round;
pen.LineJoin = LineJoin.Round;
g.DrawPath(pen, path);
}
}
}
4、实现窗体拖动功能
private bool isDragging = false;
private Point lastLocation;
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left)
{
isDragging = true;
lastLocation = e.Location;
}
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (isDragging)
{
this.Location = new Point(
(this.Location.X - lastLocation.X) + e.X,
(this.Location.Y - lastLocation.Y) + e.Y
);
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
isDragging = false;
}
5、添加窗体阴影效果
private bool enableShadow = true;
private const int CS_DROPSHADOW = 0x20000;
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
if (enableShadow)
{
cp.ClassStyle |= CS_DROPSHADOW;
}
return cp;
}
}
// 启用/禁用阴影
public bool EnableShadow
{
get { return enableShadow; }
set
{
enableShadow = value;
this.RecreateHandle();
}
}
6、示例使用代码
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
RoundedForm form = new RoundedForm();
form.CornerRadius = 20;
form.BorderColor = Color.FromArgb(64, 64, 64);
form.BackgroundColor = Color.White;
Button closeButton = new Button();
closeButton.Text = "关闭";
closeButton.Location = new Point(form.Width - 100, 20);
closeButton.Click += (s, e) => form.Close();
form.Controls.Add(closeButton);
Application.Run(form);
}
效果
注意事项
1、性能优化建议
启用双缓冲 (DoubleBuffered) 避免画面闪烁;
控制圆角半径大小,避免过大影响性能;
注意及时释放 GDI+ 资源,如 GraphicsPath、Pen、Brush;
对于复杂绘制,可考虑异步渲染或局部刷新。
2、常见问题及解决办法
窗体出现锯齿:检查是否启用了抗锯齿(SmoothingMode.AntiAlias);
拖动不流畅:优化鼠标事件处理逻辑;
控件超出圆角范围:合理设置控件位置或限制布局;
阴影未生效:确认操作系统支持阴影效果(部分系统需启用 DWM)。
总结
通过本文的详细介绍和完整代码实现,我们了解了如何使用 C# 和 GDI+ 开发一个具有圆角、边框、背景色、拖动功能和阴影效果的自定义 WinForm 窗体。该技术不仅提升了应用的视觉表现力,也为后续更复杂的 UI 定制打下了良好基础。
不管用于制作登录界面、弹出窗口还是现代风格的应用程序,圆角窗体都是一种简单而有效的美化手段。希望本文能帮助大家掌握这一实用技能,在实际项目中灵活运用!
最后
如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。
也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!
优秀是一种习惯,欢迎大家留言学习!
作者:技术老小子
出处:mp.weixin.qq.com/s/K6c99pho4q-S_yl1zvGCPA
声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!