编辑
2025-02-24
C# 应用
00
请注意,本文编写于 71 天前,最后修改于 71 天前,其中某些信息可能已经过时。

目录

简介
实现原理
完整代码实现
创建基础窗体类
实现圆角路径创建方法
重写OnPaint方法实现自定义绘制
实现窗体拖动功能
示例使用代码
完整代码
使用注意事项
总结

简介

在现代UI设计中,圆角窗体已经成为一种流行的设计元素。本文将详细介绍如何使用C#和GDI+技术来创建一个美观的圆角窗体,包括窗体的绘制、拖动、边框效果等完整功能。

实现原理

圆角窗体的实现主要基于以下几个关键技术点:

  1. 使用 GraphicsPath 创建圆角路径
  2. 使用 Region 设置窗体形状
  3. 重写窗体的 OnPaint 方法实现自定义绘制
  4. 实现窗体拖动功能

完整代码实现

创建基础窗体类

C#
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, true); this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); this.SetStyle(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(); } } }

实现圆角路径创建方法

C#
private GraphicsPath CreateRoundedPath(Rectangle rect, int radius) { // 创建圆角路径 GraphicsPath path = new GraphicsPath(); // 定义圆角矩形的各个部分 int diameter = radius * 2; Rectangle arcRect = new Rectangle(rect.Location, new Size(diameter, diameter)); // 左上角 path.AddArc(arcRect, 180, 90); // 上边 arcRect.X = rect.Right - diameter; path.AddArc(arcRect, 270, 90); // 右下角 arcRect.Y = rect.Bottom - diameter; path.AddArc(arcRect, 0, 90); // 左下角 arcRect.X = rect.Left; path.AddArc(arcRect, 90, 90); // 闭合路径 path.CloseFigure(); return path; }

重写OnPaint方法实现自定义绘制

C#
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); // 获取绘图上下文并设置抗锯齿 Graphics g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; // 创建绘制区域 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)) { g.DrawPath(pen, path); } } }

实现窗体拖动功能

C#
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; }

示例使用代码

C#
public class Program { [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); } }

完整代码

C#
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace AppWindows { public partial class RoundedForm : Form { // 圆角半径 private int cornerRadius = 20; // 窗体边框颜色 private Color borderColor = Color.FromArgb(100, 100, 100); // 窗体背景色 private Color backgroundColor = Color.White; public RoundedForm() { InitializeComponent(); // 设置窗体基本属性 this.FormBorderStyle = FormBorderStyle.None; this.DoubleBuffered = true; this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); this.SetStyle(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(); } } 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; } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); // 获取绘图上下文并设置抗锯齿 Graphics g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; e.Graphics.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; e.Graphics.DrawPath(pen, path); } } } 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; } // 添加阴影相关属性 private bool enableShadow = true; private Color shadowColor = Color.FromArgb(100, 0, 0, 0); private int shadowDepth = 6; protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; if (enableShadow) { cp.ClassStyle |= 0x20000; // CS_DROPSHADOW } return cp; } } // 阴影开关属性 public bool EnableShadow { get { return enableShadow; } set { enableShadow = value; this.RecreateHandle(); } } } }

image.png

使用注意事项

  1. 性能优化
    • 使用双缓冲避免闪烁
    • 适当设置圆角半径,过大的半径可能影响性能
    • 注意及时释放GDI+资源
  2. 常见问题解决
    • 如果窗体出现锯齿,检查是否启用了抗锯齿
    • 如果拖动不流畅,可以优化拖动代码
    • 如果控件超出圆角范围,需要正确设置控件位置

总结

本文详细介绍了如何使用C#和GDI+技术实现圆角窗体,包括基本绘制、拖动功能、阴影效果等。通过合理使用GDI+的绘图功能,我们可以创建出美观且实用的自定义窗体。在实际应用中,可以根据需求进行进一步的定制和

本文作者:rick

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!