开源 C# 快速开发(六)自定义控件--圆环
文章的目的为了记录使用C# 开发学习的经历。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。
相关链接:
开源 C# 快速开发(一)基础知识
开源 C# 快速开发(二)基础控件
开源 C# 快速开发(三)复杂控件
开源 C# 快速开发(四)自定义控件--波形图
开源 C# 快速开发(五)自定义控件--仪表盘
开源 C# 快速开发(六)自定义控件--圆环
开源 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(); // 触发重绘,立即显示新颜色
}
2. 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);}
}
3. 函数调用关系图
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;}}
}
三、效果演示
可以选择各种控件参数设置,点击按钮,圆环效果进行更新。