文章的目的为了记录使用C# 开发学习的经历。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。
相关链接:
推荐链接:
开源 C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客
开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客
开源 C# .net mvc 开发(三)WEB内外网访问-CSDN博客
开源 C# .net mvc 开发(四)工程结构、页面提交以及显示-CSDN博客
开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客
开源 C# .net mvc 开发(六)发送邮件、定时以及CMD编程-CSDN博客
开源 C# .net mvc 开发(七)动态图片、动态表格和json数据生成-CSDN博客
开源 C# .net mvc 开发(八)IIS Express轻量化Web服务器的配置和使用-CSDN博客
开源 C# .net mvc 开发(九)websocket--服务器与客户端的实时通信-CSDN博客
本章节主要内容是:圆环进度控件。
目录:
1.源码分析
2.所有源码
3.效果演示
一、源码分析1. CircularProgress 类详细函数分析
1.1 构造函数 - CircularProgress()
public CircularProgress()
{
// 启用双缓冲,减少绘制闪烁
this.DoubleBuffered = true;
// 设置控件默认尺寸为200x200像素
this.Size = new Size(200, 200);
// 配置控件样式标志,优化绘制性能:
// AllPaintingInWmPaint - 控件忽略WM_ERASEBKGND窗口消息,减少闪烁
// UserPaint - 控件自行绘制,而不是系统绘制
// ResizeRedraw - 尺寸改变时自动重绘
// OptimizedDoubleBuffer - 双缓冲支持
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.ResizeRedraw |
ControlStyles.OptimizedDoubleBuffer, true);
// 初始化文本字体:Segoe UI,12号,粗体
_textFont = new Font("Segoe UI", 12, FontStyle.Bold);
}
1.2 核心绘制函数 - OnPaint(PaintEventArgs e)
protected override void OnPaint(PaintEventArgs e)
{
// 调用基类绘制方法,确保基础绘制完成
base.OnPaint(e);
// 获取Graphics对象用于绘制
Graphics g = e.Graphics;
// 设置高质量绘制模式:
g.SmoothingMode = SmoothingMode.AntiAlias; // 抗锯齿
g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; // 清晰文本渲染
g.PixelOffsetMode = PixelOffsetMode.HighQuality; // 高质量像素偏移
// 1. 绘制圆角矩形背景
using (GraphicsPath path = CreateRoundRectPath(this.ClientRectangle, 15))
using (SolidBrush backBrush = new SolidBrush(_backgroundColor))
{
g.FillPath(backBrush, path); // 填充背景色
// 绘制1像素宽的灰色边框
using (Pen borderPen = new Pen(Color.FromArgb(200, 200, 200), 1))
{
g.DrawPath(borderPen, path);
}
}
// 2. 计算圆环绘制区域
// 内边距 = 基础内边距10 + 发光大小(为发光效果留空间)
int padding = 10 + _glowSize;
// 圆环直径 = 控件宽高的最小值 - 两边内边距
int ringDiameter = Math.Min(this.Width, this.Height) - (padding * 2);
// 计算圆环居中位置
int x = (this.Width - ringDiameter) / 2;
int y = (this.Height - ringDiameter) / 2;
Rectangle rect = new Rectangle(x, y, ringDiameter, ringDiameter);
// 3. 调整圆环矩形(为圆环宽度留出空间)
int ringPadding = _ringWidth / 2 + 2; // 半宽+2像素缓冲
Rectangle ringRect = new Rectangle(
rect.X + ringPadding, // 左边界内缩
rect.Y + ringPadding, // 上边界内缩
rect.Width - ringPadding * 2, // 宽度减少两边内缩
rect.Height - ringPadding * 2 // 高度减少两边内缩
);
// 4. 绘制发光效果(如果有进度且启用发光)
if (_showGlow && _value > 0)
{
DrawGlowEffect(g, ringRect); // 参数:Graphics对象,圆环矩形区域
}
// 5. 绘制背景圆环(完整的360度圆环)
using (Pen backPen = new Pen(_ringBackColor, _ringWidth))
{
backPen.StartCap = LineCap.Round; // 圆角起始端
backPen.EndCap = LineCap.Round; // 圆角结束端
g.DrawArc(backPen, ringRect, 0, 360); // 绘制完整圆环
}
// 6. 绘制进度圆环(根据当前进度值)
if (_value > 0)
{
using (Pen progressPen = CreateProgressPen(ringRect)) // 创建进度画笔
{
// 计算进度角度:360度 × (当前值/最大值)
float angle = 360f * _value / _maximum;
// 从起始角度绘制指定角度的圆弧
g.DrawArc(progressPen, ringRect, _startAngle, angle);
}
}
// 7. 绘制中心文本(如果启用文本显示)
if (_showText)
{
DrawCenterText(g, ringDiameter); // 参数:Graphics对象,圆环直径
}
}
1.3 CreateProgressPen(Rectangle ringRect) - 创建进度画笔
private Pen CreateProgressPen(Rectangle ringRect)
{
// 创建基础进度画笔:指定颜色和宽度
Pen progressPen = new Pen(_ringColor, _ringWidth);
// 设置画笔端点样式为圆形
progressPen.StartCap = LineCap.Round;
progressPen.EndCap = LineCap.Round;
// 检查是否启用渐变效果且圆环足够大(避免小尺寸下的渐变问题)
if (_useGradient && ringRect.Width > 50)
{
// 计算渐变结束颜色:
// 如果未指定渐变颜色,使用系统方法将主色调亮30%
Color gradientEnd = _gradientColor.IsEmpty ?
ControlPaint.Light(_ringColor, 0.3f) : _gradientColor;
// 创建线性渐变画笔:从左上到右下对角线渐变
using (var brush = new LinearGradientBrush(
new Point(ringRect.Left, ringRect.Top), // 渐变起点
new Point(ringRect.Right, ringRect.Bottom), // 渐变终点
_ringColor, // 起始颜色
gradientEnd)) // 结束颜色
{
progressPen.Brush = brush; // 将渐变画笔应用到钢笔
}
}
return progressPen; // 返回配置好的画笔
}
1.4 DrawGlowEffect(Graphics g, Rectangle ringRect) - 绘制发光效果
private void DrawGlowEffect(Graphics g, Rectangle ringRect)
{
// 从最大发光尺寸开始,逐层向内绘制
for (int i = _glowSize; i > 0; i--)
{
// 创建发光效果画笔:
// 颜色:主色带透明度(30 - i*5),外层更透明
// 宽度:基础宽度 + i*2,外层更宽
using (Pen glowPen = new Pen(Color.FromArgb(30 - i * 5, _ringColor), _ringWidth + i * 2))
{
glowPen.StartCap = LineCap.Round; // 圆角端点
glowPen.EndCap = LineCap.Round;
// 计算当前进度对应的角度
float angle = 360f * _value / _maximum;
// 绘制发光圆弧(与进度圆弧相同角度)
g.DrawArc(glowPen, ringRect, _startAngle, angle);
}
}
// 循环结束后,从外到内绘制了多层半透明圆弧,形成发光效果
}
1.5 DrawCenterText(Graphics g, int ringDiameter) - 绘制中心文本
private void DrawCenterText(Graphics g, int ringDiameter)
{
// 根据格式字符串生成显示文本(如:"45%")
string text = string.Format(_textFormat, _value);
// 动态计算字体大小:基于圆环直径的1/8,最小8号字
float fontSize = Math.Max(8, ringDiameter / 8f);
// 创建字体对象(使用原字体的字体系列和样式,但调整大小)
using (Font font = new Font(_textFont.FontFamily, fontSize, _textFont.Style))
using (SolidBrush textBrush = new SolidBrush(_textColor)) // 文本颜色画笔
{
// 测量文本尺寸,用于居中计算
SizeF textSize = g.MeasureString(text, font);
// 计算文本居中位置
PointF textLocation = new PointF(
(this.Width - textSize.Width) / 2, // 水平居中
(this.Height - textSize.Height) / 2 // 垂直居中
);
// 如果启用阴影效果,先绘制阴影层
if (_showShadow)
{
using (SolidBrush shadowBrush = new SolidBrush(_shadowColor))
{
// 在文本位置右下方偏移绘制阴影
g.DrawString(text, font, shadowBrush,
textLocation.X + _shadowOffset, // X偏移
textLocation.Y + _shadowOffset); // Y偏移
}
}
// 绘制主文本(在阴影上方)
g.DrawString(text, font, textBrush, textLocation);
}
// using语句自动释放字体和画笔资源
}
1.6 CreateRoundRectPath(Rectangle rect, int radius) - 创建圆角矩形路径
private GraphicsPath CreateRoundRectPath(Rectangle rect, int radius)
{
GraphicsPath path = new GraphicsPath(); // 创建空路径
// 按顺时针方向添加四个圆弧和连接线:
// 1. 左上角圆弧:从180度到270度(左上角)
path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);
// 2. 上边线 + 右上角圆弧:从270度到0度(右上角)
path.AddArc(rect.X + rect.Width - radius, rect.Y, radius, radius, 270, 90);
// 3. 右边线 + 右下角圆弧:从0度到90度(右下角)
path.AddArc(rect.X + rect.Width - radius, rect.Y + rect.Height - radius,
radius, radius, 0, 90);
// 4. 底边线 + 左下角圆弧:从90度到180度(左下角)
path.AddArc(rect.X, rect.Y + rect.Height - radius, radius, radius, 90, 90);
// 闭合路径(连接回起点)
path.CloseFigure();
return path; // 返回完整的圆角矩形路径
}
1.7 ApplyColorScheme(ColorScheme scheme) - 应用颜色主题
public void ApplyColorScheme(ColorScheme scheme)
{
// 根据枚举值选择对应的颜色组合
switch (scheme)
{
case ColorScheme.Blue:
// 调用SetColors设置:主色,渐变色,文本色
SetColors(Color.FromArgb(0, 120, 215),
Color.FromArgb(64, 156, 255),
Color.FromArgb(0, 90, 158));
break;
case ColorScheme.Green:
SetColors(Color.FromArgb(46, 204, 113),
Color.FromArgb(88, 214, 141),
Color.FromArgb(39, 174, 96));
break;
// ... 其他13种颜色方案类似
case ColorScheme.Sunset:
SetColors(Color.FromArgb(255, 94, 77),
Color.FromArgb(255, 145, 114),
Color.FromArgb(255, 61, 38));
// 特殊方案额外设置渐变颜色
_gradientColor = Color.FromArgb(255, 193, 7);
break;
// ... 更多case语句
}
}
1.8 SetColors(Color ringColor, Color gradientColor, Color textColor) - 设置颜色
private void SetColors(Color ringColor, Color gradientColor, Color textColor)
{
_ringColor = ringColor; // 设置圆环主色
_gradientColor = gradientColor; // 设置渐变色
_textColor = textColor; // 设置文本颜色
this.Invalidate(); // 触发重绘,立即显示新颜色
}
- Form1 类详细函数分析
2.1 SetupControls() - 初始化所有界面控件
private void SetupControls()
{
// 窗体基本设置
this.Text = "增强版圆环进度控件演示";
this.Size = new Size(600, 700);
this.StartPosition = FormStartPosition.CenterScreen;
this.BackColor = Color.White;
// 创建并配置圆环进度控件
circularProgress = new CircularProgress();
circularProgress.Location = new Point(200, 30); // 居中偏上位置
circularProgress.Size = new Size(200, 200);
// ... 各种属性设置
// 创建滑块控件用于精确控制进度
trackBar = new TrackBar();
trackBar.Location = new Point(50, 250); // 圆环下方
trackBar.Size = new Size(500, 45);
trackBar.Minimum = 0;
trackBar.Maximum = 100;
trackBar.Value = 45;
trackBar.TickFrequency = 10; // 每10个单位一个刻度
trackBar.ValueChanged += TrackBar_ValueChanged; // 事件绑定
// 创建增减按钮
btnIncrease = CreateStyledButton("+10", Color.FromArgb(0, 120, 215), 50, 310);
btnIncrease.Click += BtnIncrease_Click;
btnDecrease = CreateStyledButton("-10", Color.FromArgb(200, 200, 200), 150, 310);
btnDecrease.Click += BtnDecrease_Click;
// 创建颜色方案下拉选择框
cmbColorScheme = new ComboBox();
cmbColorScheme.Location = new Point(250, 310);
cmbColorScheme.Size = new Size(200, 25);
cmbColorScheme.DropDownStyle = ComboBoxStyle.DropDownList; // 禁止编辑
// 填充枚举值到下拉框
foreach (ColorScheme scheme in Enum.GetValues(typeof(ColorScheme)))
{
cmbColorScheme.Items.Add(GetColorSchemeName(scheme));
}
cmbColorScheme.SelectedIndex = (int)ColorScheme.Ocean; // 默认选择
cmbColorScheme.SelectedIndexChanged += CmbColorScheme_SelectedIndexChanged;
// 创建效果控制复选框
chkGradient = CreateCheckBox("渐变效果", 50, 360);
chkGradient.Checked = true;
chkGradient.CheckedChanged += ChkGradient_CheckedChanged;
// ... 创建其他控件
// 将所有控件添加到窗体
this.Controls.AddRange(new Control[] {
circularProgress, trackBar, btnIncrease, btnDecrease, cmbColorScheme,
chkGradient, chkGlow, chkShadow, lblGlowSize, numGlowSize
});
// 创建主题预览面板
CreateThemePreviewPanel();
}
2.2 CreateStyledButton() - 创建统一样式按钮
private Button CreateStyledButton(string text, Color backColor, int x, int y)
{
return new Button()
{
Text = text, // 按钮文本
Location = new Point(x, y), // 位置坐标
Size = new Size(80, 30), // 固定尺寸
BackColor = backColor, // 背景色
// 根据背景亮度自动选择文字颜色(亮背景用黑字,暗背景用白字)
ForeColor = backColor.GetBrightness() > 0.6 ? Color.Black : Color.White,
FlatStyle = FlatStyle.Flat, // 扁平化样式
Font = new Font("Microsoft YaHei", 9) // 统一字体
};
}
2.3 CreateThemePreviewPanel() - 创建主题预览网格
private void CreateThemePreviewPanel()
{
// 创建分组容器
GroupBox groupBox = new GroupBox()
{
Text = "快速主题预览", // 分组标题
Location = new Point(50, 400), // 位置
Size = new Size(500, 200), // 尺寸
ForeColor = Color.FromArgb(64, 64, 64), // 文字颜色
Font = new Font("Microsoft YaHei", 9, FontStyle.Bold) // 粗体标题
};
// 创建流式布局面板,支持自动排列和滚动
FlowLayoutPanel flowPanel = new FlowLayoutPanel()
{
Location = new Point(10, 20), // 分组框内位置
Size = new Size(480, 170), // 内部尺寸
AutoScroll = true // 启用滚动条
};
// 为每个颜色主题创建预览按钮
foreach (ColorScheme scheme in Enum.GetValues(typeof(ColorScheme)))
{
Button themeBtn = new Button()
{
Text = GetColorSchemeName(scheme), // 显示主题名称
Size = new Size(100, 30), // 按钮尺寸
BackColor = GetThemeBaseColor(scheme), // 使用主题主色作为背景
ForeColor = Color.White, // 白色文字
FlatStyle = FlatStyle.Flat, // 扁平样式
Tag = scheme, // 存储枚举值用于事件处理
Font = new Font("Microsoft YaHei", 8) // 小号字体
};
themeBtn.Click += ThemeBtn_Click; // 绑定点击事件
flowPanel.Controls.Add(themeBtn); // 添加到流式面板
}
groupBox.Controls.Add(flowPanel); // 将面板添加到分组框
this.Controls.Add(groupBox); // 将分组框添加到窗体
}
2.4 事件处理函数示例
private void TrackBar_ValueChanged(object sender, EventArgs e)
{
// 同步滑块值和进度控件值
circularProgress.Value = trackBar.Value;
}
private void BtnIncrease_Click(object sender, EventArgs e)
{
// 增加10个单位,并同步滑块
circularProgress.Value += 10;
trackBar.Value = circularProgress.Value;
}
private void CmbColorScheme_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbColorScheme.SelectedIndex >= 0)
{
// 将选中索引转换为枚举值并应用主题
ColorScheme scheme = (ColorScheme)cmbColorScheme.SelectedIndex;
circularProgress.ApplyColorScheme(scheme);
}
}
- 函数调用关系图
OnPaint() 主绘制流程
├── CreateRoundRectPath() // 创建背景路径
├── DrawGlowEffect() // 绘制发光效果
├── CreateProgressPen() // 创建进度画笔
└── DrawCenterText() // 绘制中心文本
属性设置流程
├── 任何属性setter → Invalidate() → OnPaint()
└── ApplyColorScheme() → SetColors() → Invalidate()
窗体交互流程
├── 用户操作 → 事件处理函数 → 修改CircularProgress属性
└── CircularProgress属性变化 → 自动重绘 → 视觉更新
这个详细分析展示了每个函数的精确功能、参数用途、内部逻辑和相互调用关系,体现了良好的面向对象设计和图形编程实践。
二、所有源码
CircularProgress.cs源码
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;
namespace _5_cycleCtrl
{
public class CircularProgress : Control
{
private int _value = 0;
private int _maximum = 100;
private int _ringWidth = 20;
private Color _ringColor = Color.FromArgb(0, 120, 215);
private Color _ringBackColor = Color.FromArgb(240, 240, 240);
private Color _backgroundColor = Color.White;
private bool _showText = true;
private string _textFormat = "{0}%";
private Font _textFont;
private Color _textColor = Color.FromArgb(64, 64, 64);
private bool _showShadow = true;
private Color _shadowColor = Color.FromArgb(100, 0, 0, 0);
private int _shadowOffset = 2;
private float _startAngle = 270f;
private bool _useGradient = true;
private Color _gradientColor = Color.Empty;
private bool _showGlow = true;
private int _glowSize = 5;
public CircularProgress()
{
this.DoubleBuffered = true;
this.Size = new Size(200, 200);
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.ResizeRedraw |
ControlStyles.OptimizedDoubleBuffer, true);
_textFont = new Font("Segoe UI", 12, FontStyle.Bold);
}
// 基本属性
public int Value
{
get { return _value; }
set
{
_value = Math.Max(0, Math.Min(_maximum, value));
this.Invalidate();
}
}
public int Maximum
{
get { return _maximum; }
set
{
_maximum = Math.Max(1, value);
_value = Math.Min(_value, _maximum);
this.Invalidate();
}
}
public int RingWidth
{
get { return _ringWidth; }
set
{
_ringWidth = Math.Max(1, value);
this.Invalidate();
}
}
public Color RingColor
{
get { return _ringColor; }
set
{
_ringColor = value;
this.Invalidate();
}
}
public Color RingBackColor
{
get { return _ringBackColor; }
set
{
_ringBackColor = value;
this.Invalidate();
}
}
public Color BackgroundColor
{
get { return _backgroundColor; }
set
{
_backgroundColor = value;
this.Invalidate();
}
}
// 文本相关属性
public bool ShowText
{
get { return _showText; }
set
{
_showText = value;
this.Invalidate();
}
}
public string TextFormat
{
get { return _textFormat; }
set
{
_textFormat = value;
this.Invalidate();
}
}
public Font TextFont
{
get { return _textFont; }
set
{
_textFont = value;
this.Invalidate();
}
}
public Color TextColor
{
get { return _textColor; }
set
{
_textColor = value;
this.Invalidate();
}
}
// 效果属性
public bool ShowShadow
{
get { return _showShadow; }
set
{
_showShadow = value;
this.Invalidate();
}
}
public float StartAngle
{
get { return _startAngle; }
set
{
_startAngle = value;
this.Invalidate();
}
}
public bool UseGradient
{
get { return _useGradient; }
set
{
_useGradient = value;
this.Invalidate();
}
}
public Color GradientColor
{
get { return _gradientColor; }
set
{
_gradientColor = value;
this.Invalidate();
}
}
public bool ShowGlow
{
get { return _showGlow; }
set
{
_showGlow = value;
this.Invalidate();
}
}
public int GlowSize
{
get { return _glowSize; }
set
{
_glowSize = Math.Max(0, value);
this.Invalidate();
}
}
// 预设颜色主题
public void ApplyColorScheme(ColorScheme scheme)
{
switch (scheme)
{
case ColorScheme.Blue:
SetColors(Color.FromArgb(0, 120, 215), Color.FromArgb(64, 156, 255), Color.FromArgb(0, 90, 158));
break;
case ColorScheme.Green:
SetColors(Color.FromArgb(46, 204, 113), Color.FromArgb(88, 214, 141), Color.FromArgb(39, 174, 96));
break;
case ColorScheme.Red:
SetColors(Color.FromArgb(231, 76, 60), Color.FromArgb(236, 112, 99), Color.FromArgb(192, 57, 43));
break;
case ColorScheme.Purple:
SetColors(Color.FromArgb(155, 89, 182), Color.FromArgb(175, 122, 197), Color.FromArgb(142, 68, 173));
break;
case ColorScheme.Orange:
SetColors(Color.FromArgb(230, 126, 34), Color.FromArgb(235, 151, 78), Color.FromArgb(211, 84, 0));
break;
case ColorScheme.Teal:
SetColors(Color.FromArgb(22, 160, 133), Color.FromArgb(72, 201, 176), Color.FromArgb(19, 141, 117));
break;
case ColorScheme.Pink:
SetColors(Color.FromArgb(255, 107, 129), Color.FromArgb(255, 148, 164), Color.FromArgb(255, 71, 97));
break;
case ColorScheme.Gold:
SetColors(Color.FromArgb(241, 196, 15), Color.FromArgb(245, 215, 110), Color.FromArgb(213, 172, 13));
break;
case ColorScheme.Cyan:
SetColors(Color.FromArgb(0, 188, 212), Color.FromArgb(77, 208, 225), Color.FromArgb(0, 151, 167));
break;
case ColorScheme.Indigo:
SetColors(Color.FromArgb(63, 81, 181), Color.FromArgb(106, 120, 205), Color.FromArgb(48, 63, 159));
break;
case ColorScheme.Sunset:
SetColors(Color.FromArgb(255, 94, 77), Color.FromArgb(255, 145, 114), Color.FromArgb(255, 61, 38));
_gradientColor = Color.FromArgb(255, 193, 7);
break;
case ColorScheme.Ocean:
SetColors(Color.FromArgb(0, 150, 199), Color.FromArgb(77, 184, 214), Color.FromArgb(0, 119, 190));
_gradientColor = Color.FromArgb(0, 180, 216);
break;
case ColorScheme.Forest:
SetColors(Color.FromArgb(56, 142, 60), Color.FromArgb(102, 187, 106), Color.FromArgb(46, 125, 50));
break;
case ColorScheme.Lavender:
SetColors(Color.FromArgb(179, 157, 219), Color.FromArgb(204, 191, 231), Color.FromArgb(149, 125, 173));
break;
case ColorScheme.Coral:
SetColors(Color.FromArgb(255, 138, 101), Color.FromArgb(255, 173, 148), Color.FromArgb(255, 112, 67));
break;
}
}
private void SetColors(Color ringColor, Color gradientColor, Color textColor)
{
_ringColor = ringColor;
_gradientColor = gradientColor;
_textColor = textColor;
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
// 绘制背景(圆角矩形)
using (GraphicsPath path = CreateRoundRectPath(this.ClientRectangle, 15))
using (SolidBrush backBrush = new SolidBrush(_backgroundColor))
{
g.FillPath(backBrush, path);
using (Pen borderPen = new Pen(Color.FromArgb(200, 200, 200), 1))
{
g.DrawPath(borderPen, path);
}
}
// 计算圆环的矩形区域
int padding = 10 + _glowSize;
int ringDiameter = Math.Min(this.Width, this.Height) - (padding * 2);
int x = (this.Width - ringDiameter) / 2;
int y = (this.Height - ringDiameter) / 2;
Rectangle rect = new Rectangle(x, y, ringDiameter, ringDiameter);
// 调整圆环矩形
int ringPadding = _ringWidth / 2 + 2;
Rectangle ringRect = new Rectangle(
rect.X + ringPadding,
rect.Y + ringPadding,
rect.Width - ringPadding * 2,
rect.Height - ringPadding * 2
);
// 绘制发光效果
if (_showGlow && _value > 0)
{
DrawGlowEffect(g, ringRect);
}
// 绘制圆环底色
using (Pen backPen = new Pen(_ringBackColor, _ringWidth))
{
backPen.StartCap = LineCap.Round;
backPen.EndCap = LineCap.Round;
g.DrawArc(backPen, ringRect, 0, 360);
}
// 绘制进度圆环
if (_value > 0)
{
using (Pen progressPen = CreateProgressPen(ringRect))
{
float angle = 360f * _value / _maximum;
g.DrawArc(progressPen, ringRect, _startAngle, angle);
}
}
// 绘制中心文本
if (_showText)
{
DrawCenterText(g, ringDiameter);
}
}
private Pen CreateProgressPen(Rectangle ringRect)
{
Pen progressPen = new Pen(_ringColor, _ringWidth);
progressPen.StartCap = LineCap.Round;
progressPen.EndCap = LineCap.Round;
if (_useGradient && ringRect.Width > 50)
{
Color gradientEnd = _gradientColor.IsEmpty ?
ControlPaint.Light(_ringColor, 0.3f) : _gradientColor;
using (var brush = new LinearGradientBrush(
new Point(ringRect.Left, ringRect.Top),
new Point(ringRect.Right, ringRect.Bottom),
_ringColor,
gradientEnd))
{
progressPen.Brush = brush;
}
}
return progressPen;
}
private void DrawGlowEffect(Graphics g, Rectangle ringRect)
{
for (int i = _glowSize; i > 0; i--)
{
using (Pen glowPen = new Pen(Color.FromArgb(30 - i * 5, _ringColor), _ringWidth + i * 2))
{
glowPen.StartCap = LineCap.Round;
glowPen.EndCap = LineCap.Round;
float angle = 360f * _value / _maximum;
g.DrawArc(glowPen, ringRect, _startAngle, angle);
}
}
}
private void DrawCenterText(Graphics g, int ringDiameter)
{
string text = string.Format(_textFormat, _value);
float fontSize = Math.Max(8, ringDiameter / 8f);
using (Font font = new Font(_textFont.FontFamily, fontSize, _textFont.Style))
using (SolidBrush textBrush = new SolidBrush(_textColor))
{
SizeF textSize = g.MeasureString(text, font);
PointF textLocation = new PointF(
(this.Width - textSize.Width) / 2,
(this.Height - textSize.Height) / 2
);
if (_showShadow)
{
using (SolidBrush shadowBrush = new SolidBrush(_shadowColor))
{
g.DrawString(text, font, shadowBrush,
textLocation.X + _shadowOffset,
textLocation.Y + _shadowOffset);
}
}
g.DrawString(text, font, textBrush, textLocation);
}
}
private GraphicsPath CreateRoundRectPath(Rectangle rect, int radius)
{
GraphicsPath path = new GraphicsPath();
path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);
path.AddArc(rect.X + rect.Width - radius, rect.Y, radius, radius, 270, 90);
path.AddArc(rect.X + rect.Width - radius, rect.Y + rect.Height - radius,
radius, radius, 0, 90);
path.AddArc(rect.X, rect.Y + rect.Height - radius, radius, radius, 90, 90);
path.CloseFigure();
return path;
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.Invalidate();
}
protected override void Dispose(bool disposing)
{
if (disposing && _textFont != null)
{
_textFont.Dispose();
}
base.Dispose(disposing);
}
}
// 颜色主题枚举
public enum ColorScheme
{
Blue,
Green,
Red,
Purple,
Orange,
Teal,
Pink,
Gold,
Cyan,
Indigo,
Sunset,
Ocean,
Forest,
Lavender,
Coral
}
}
Form1.cs源码
using System;
using System.Drawing;
using System.Windows.Forms;
namespace _5_cycleCtrl
{
public partial class Form1 : Form
{
private CircularProgress circularProgress;
private Button btnIncrease, btnDecrease;
private ComboBox cmbColorScheme;
private TrackBar trackBar;
private CheckBox chkGradient, chkGlow, chkShadow;
private NumericUpDown numGlowSize;
public Form1()
{
InitializeComponent();
SetupControls();
}
private void SetupControls()
{
this.Text = "增强版圆环进度控件演示";
this.Size = new Size(600, 700);
this.StartPosition = FormStartPosition.CenterScreen;
this.BackColor = Color.White;
// 创建圆环控件
circularProgress = new CircularProgress();
circularProgress.Location = new Point(200, 30);
circularProgress.Size = new Size(200, 200);
circularProgress.BackgroundColor = Color.White;
circularProgress.RingBackColor = Color.FromArgb(240, 240, 240);
circularProgress.RingWidth = 15;
circularProgress.TextFormat = "{0}%";
circularProgress.Maximum = 100;
circularProgress.Value = 45;
circularProgress.ShowShadow = true;
circularProgress.UseGradient = true;
circularProgress.ShowGlow = true;
// 应用初始颜色主题
circularProgress.ApplyColorScheme(ColorScheme.Ocean);
// 创建滑块控件
trackBar = new TrackBar();
trackBar.Location = new Point(50, 250);
trackBar.Size = new Size(500, 45);
trackBar.Minimum = 0;
trackBar.Maximum = 100;
trackBar.Value = 45;
trackBar.TickFrequency = 10;
trackBar.ValueChanged += TrackBar_ValueChanged;
// 创建按钮
btnIncrease = CreateStyledButton("+10", Color.FromArgb(0, 120, 215), 50, 310);
btnIncrease.Click += BtnIncrease_Click;
btnDecrease = CreateStyledButton("-10", Color.FromArgb(200, 200, 200), 150, 310);
btnDecrease.Click += BtnDecrease_Click;
// 创建颜色方案选择
cmbColorScheme = new ComboBox();
cmbColorScheme.Location = new Point(250, 310);
cmbColorScheme.Size = new Size(200, 25);
cmbColorScheme.DropDownStyle = ComboBoxStyle.DropDownList;
// 添加所有颜色主题
foreach (ColorScheme scheme in Enum.GetValues(typeof(ColorScheme)))
{
cmbColorScheme.Items.Add(GetColorSchemeName(scheme));
}
cmbColorScheme.SelectedIndex = (int)ColorScheme.Ocean;
cmbColorScheme.SelectedIndexChanged += CmbColorScheme_SelectedIndexChanged;
// 创建效果控制
chkGradient = CreateCheckBox("渐变效果", 50, 360);
chkGradient.Checked = true;
chkGradient.CheckedChanged += ChkGradient_CheckedChanged;
chkGlow = CreateCheckBox("发光效果", 150, 360);
chkGlow.Checked = true;
chkGlow.CheckedChanged += ChkGlow_CheckedChanged;
chkShadow = CreateCheckBox("文本阴影", 250, 360);
chkShadow.Checked = true;
chkShadow.CheckedChanged += ChkShadow_CheckedChanged;
// 发光大小控制
Label lblGlowSize = new Label()
{
Text = "发光大小:",
Location = new Point(350, 362),
Size = new Size(60, 20),
ForeColor = Color.FromArgb(64, 64, 64)
};
numGlowSize = new NumericUpDown()
{
Location = new Point(420, 360),
Size = new Size(50, 20),
Minimum = 0,
Maximum = 10,
Value = 5
};
numGlowSize.ValueChanged += NumGlowSize_ValueChanged;
// 添加到窗体
this.Controls.AddRange(new Control[] {
circularProgress, trackBar, btnIncrease, btnDecrease, cmbColorScheme,
chkGradient, chkGlow, chkShadow, lblGlowSize, numGlowSize
});
// 创建主题预览面板
CreateThemePreviewPanel();
}
private Button CreateStyledButton(string text, Color backColor, int x, int y)
{
return new Button()
{
Text = text,
Location = new Point(x, y),
Size = new Size(80, 30),
BackColor = backColor,
ForeColor = backColor.GetBrightness() > 0.6 ? Color.Black : Color.White,
FlatStyle = FlatStyle.Flat,
Font = new Font("Microsoft YaHei", 9)
};
}
private CheckBox CreateCheckBox(string text, int x, int y)
{
return new CheckBox()
{
Text = text,
Location = new Point(x, y),
Size = new Size(80, 20),
ForeColor = Color.FromArgb(64, 64, 64),
Font = new Font("Microsoft YaHei", 9)
};
}
private void CreateThemePreviewPanel()
{
GroupBox groupBox = new GroupBox()
{
Text = "快速主题预览",
Location = new Point(50, 400),
Size = new Size(500, 200),
ForeColor = Color.FromArgb(64, 64, 64),
Font = new Font("Microsoft YaHei", 9, FontStyle.Bold)
};
FlowLayoutPanel flowPanel = new FlowLayoutPanel()
{
Location = new Point(10, 20),
Size = new Size(480, 170),
AutoScroll = true
};
// 创建主题预览按钮
foreach (ColorScheme scheme in Enum.GetValues(typeof(ColorScheme)))
{
Button themeBtn = new Button()
{
Text = GetColorSchemeName(scheme),
Size = new Size(100, 30),
BackColor = GetThemeBaseColor(scheme),
ForeColor = Color.White,
FlatStyle = FlatStyle.Flat,
Tag = scheme,
Font = new Font("Microsoft YaHei", 8)
};
themeBtn.Click += ThemeBtn_Click;
flowPanel.Controls.Add(themeBtn);
}
groupBox.Controls.Add(flowPanel);
this.Controls.Add(groupBox);
}
private string GetColorSchemeName(ColorScheme scheme)
{
return scheme.ToString();
}
private Color GetThemeBaseColor(ColorScheme scheme)
{
switch (scheme)
{
case ColorScheme.Blue: return Color.FromArgb(0, 120, 215);
case ColorScheme.Green: return Color.FromArgb(46, 204, 113);
case ColorScheme.Red: return Color.FromArgb(231, 76, 60);
case ColorScheme.Purple: return Color.FromArgb(155, 89, 182);
case ColorScheme.Orange: return Color.FromArgb(230, 126, 34);
case ColorScheme.Teal: return Color.FromArgb(22, 160, 133);
case ColorScheme.Pink: return Color.FromArgb(255, 107, 129);
case ColorScheme.Gold: return Color.FromArgb(241, 196, 15);
case ColorScheme.Cyan: return Color.FromArgb(0, 188, 212);
case ColorScheme.Indigo: return Color.FromArgb(63, 81, 181);
case ColorScheme.Sunset: return Color.FromArgb(255, 94, 77);
case ColorScheme.Ocean: return Color.FromArgb(0, 150, 199);
case ColorScheme.Forest: return Color.FromArgb(56, 142, 60);
case ColorScheme.Lavender: return Color.FromArgb(179, 157, 219);
case ColorScheme.Coral: return Color.FromArgb(255, 138, 101);
default: return Color.Blue;
}
}
private void ThemeBtn_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
if (btn != null)
{
ColorScheme scheme = (ColorScheme)btn.Tag;
circularProgress.ApplyColorScheme(scheme);
cmbColorScheme.SelectedItem = GetColorSchemeName(scheme);
}
}
private void TrackBar_ValueChanged(object sender, EventArgs e)
{
circularProgress.Value = trackBar.Value;
}
private void BtnIncrease_Click(object sender, EventArgs e)
{
circularProgress.Value += 10;
trackBar.Value = circularProgress.Value;
}
private void BtnDecrease_Click(object sender, EventArgs e)
{
circularProgress.Value -= 10;
trackBar.Value = circularProgress.Value;
}
private void CmbColorScheme_SelectedIndexChanged(object sender, EventArgs e)
{
if (cmbColorScheme.SelectedIndex >= 0)
{
ColorScheme scheme = (ColorScheme)cmbColorScheme.SelectedIndex;
circularProgress.ApplyColorScheme(scheme);
}
}
private void ChkGradient_CheckedChanged(object sender, EventArgs e)
{
circularProgress.UseGradient = chkGradient.Checked;
}
private void ChkGlow_CheckedChanged(object sender, EventArgs e)
{
circularProgress.ShowGlow = chkGlow.Checked;
}
private void ChkShadow_CheckedChanged(object sender, EventArgs e)
{
circularProgress.ShowShadow = chkShadow.Checked;
}
private void NumGlowSize_ValueChanged(object sender, EventArgs e)
{
circularProgress.GlowSize = (int)numGlowSize.Value;
}
}
}
三、效果演示
可以选择各种控件参数设置,点击按钮,圆环效果进行更新。
