当前位置:首页 > 人生 > 作品墙 > 正文内容

ProgressBarF 圆环扇区进度条调用文档

作品墙12小时前


命名空间:CConUI
继承:ProgressBarBase → Control
可见性:public class ProgressBarF
默认尺寸:150 × 150(正方形)
定位:圆环扇区进度条——自适应绘制正圆;底层是背景圆,中间是可选装饰内环,主环从 12 点顺时针扫过,表示进度;中央可显示文字。


一、作用

在控件区域内绘制一个居中的正圆环,采用扇形扫过的经典进度表现方式:

  • 背景圆:ColorBack 铺满整圆;

  • 装饰内环:可选(ShowInnerRing),用 ColorCore 画一条 2px 细圆环,位于主环内侧,形成层次感;

  • 进度圆环:用 ColorCore 以 PieWidth 厚度绘制,从 12 点(-90°)顺时针扫过与 Value 对应的角度;

  • 外边框:BorderColor / BorderSize 围最外一圈;

  • 中央文字:Text / Font / ForeColor。

视觉示意

进度视觉效果
Value ≤ Min仅显示背景圆 + 装饰内环 + 边框 + 文字,主环不显示
0 < 进度 < 100%主环从 12 点方向开始顺时针扩展,弧线长度随进度增加
进度 = 100%主环扫过 360°,圆环完整一圈

与其它进度条风格对比:

  • ProgressBarB:填充式扇形(从 12 点顺时针填充到圆心);

  • ProgressBarC:从底部向两侧对称展开(填充区域);

  • ProgressBarD:水位 + 波浪(填充,动画);

  • ProgressBarE:环被切块、逐块点亮(动画 loading);

  • ProgressBarF:圆环扫过(描边弧线),中间保持空心(可选加装饰内环),视觉更“轻盈”、更“仪表盘”。


二、快速上手

using System.Drawing;
using System.Windows.Forms;
using CConUI;

// 1. 创建控件(默认 150 × 150)
var bar = new ProgressBarF();

// 2. 放入容器
bar.Parent = panel1;
bar.Location = new Point(20, 20);
// 也可 bar.Dock = DockStyle.None; bar.Size = new Size(150, 150);

// 3. 设置范围与当前值
bar.Min = 0;
bar.Max = 100;
bar.Value = 45;
bar.Text = "45%";

// 4. 外观
bar.ColorBack = Color.FromArgb(45, 45, 48);      // 背景圆
bar.ColorCore = Color.FromArgb(0, 200, 120);     // 主环 + 内环颜色
bar.BorderColor = Color.FromArgb(30, 30, 30);    // 外边框
bar.BorderSize = 2;
bar.PieWidth = 20;                                // 主环厚度
bar.ShowInnerRing = true;                         // 显示装饰内环
bar.ForeColor = Color.White;
bar.Font = new Font("Microsoft YaHei", 10F, FontStyle.Bold);

三、构造函数

public ProgressBarF()

项目说明
参数无
作用构造圆环扇区进度条
实际行为① 调用 ProgressBarBase 无参构造(基类已处理 UserPaint / 双缓冲等);
② 设置 Size = new Size(150, 150)
默认尺寸150 × 150(正方形,绘制出来就是正圆)
默认属性PieWidth = 20、ShowInnerRing = true;其它属性(Min / Max / Value / 颜色)继承基类默认
var bar = new ProgressBarF
{
    Parent = panel1,
    Location = new Point(20, 20)
};

四、公开属性

4.1 本类新增的属性

public int PieWidth

项目说明
类型int(像素)
默认20
CategoryCCon
DefaultValue20
作用主环(进度弧)的厚度,即画笔宽度
取值范围Math.Max(1, value)——自动 clamp 到 ≥1,防止画笔宽度为 0 造成绘制异常
额外保护绘制时 pw = min(PieWidth, d/2 - 1),保证厚度不超过半径,避免内圆消失、数学计算越界
副作用赋值后 Invalidate() 重绘
备注此属性同时影响装饰内环的位置:内环半径 = 外圆半径 − PieWidth − 6px 间距
bar.PieWidth = 12;   // 细环
bar.PieWidth = 30;   // 粗环

public bool ShowInnerRing

项目说明
类型bool
默认true
CategoryCCon
DefaultValuetrue
作用是否绘制装饰性的内圈细圆环:
true → 在主环内侧绘制一条 2px 宽、ColorCore 颜色的圆环;
false → 不绘制内环
副作用赋值后 Invalidate() 重绘;值未变化时不触发重绘
绘制保护内环半径 = 外圆半径 − (PieWidth + 6);若这个直径 ≤ 10px,则不绘制,避免内环缩成一点
bar.ShowInnerRing = false;   // 隐藏装饰内环
bar.ShowInnerRing = true;    // 显示

4.2 继承自 ProgressBarBase 的成员(由本类绘制逻辑引用)

成员类型在本类中的作用用法示例
Minint进度下限;计算扫过角度时的起点bar.Min = 0;
Maxint进度上限;计算扫过角度时的终点bar.Max = 100;
Valueint当前进度;决定主环的扫过角度bar.Value = 45;
ColorBackColor背景圆填充色bar.ColorBack = Color.FromArgb(45, 45, 48);
ColorCoreColor主环 + 装饰内环的颜色bar.ColorCore = Color.DodgerBlue;
BorderColorColor外圈边框颜色bar.BorderColor = Color.Black;
BorderSizeint外圈边框粗细(像素);绘制时会被 clamp 到圆半径以内bar.BorderSize = 2;

事件(如 Change / ValueChanged)请参考 ProgressBarBase。

4.3 绘制逻辑引用到的 Control 成员

成员来源说明
TextControl圆中央文字
FontControl文字字体
ForeColorControl文字颜色
ClientSizeControl计算圆直径与居中
SizeControl构造时设置为 150 × 150
Invalidate()Control属性变化后触发重绘

五、公开方法

ProgressBarF 没有新增 public 方法,全部公开方法继承自 ProgressBarBase 与 Control(如 Invalidate()、Focus()、BringToFront() 等)。

内部重写方法(protected override,外部不可直接调用)

方法可见性作用
OnPaint(PaintEventArgs e)protected override整体绘制:背景圆 → 装饰内环 → 进度弧 → 文字 → 外边框

六、公开成员速查表

成员来源类型说明
ProgressBarF()本类构造函数默认尺寸 150×150,PieWidth=20,ShowInnerRing=true
PieWidth本类属性(int)主环厚度(默认 20,≥1)
ShowInnerRing本类属性(bool)是否绘制装饰内环(默认 true)
Min / Max / ValueProgressBarBase属性(int)进度范围与当前值
ColorBack / ColorCore / BorderColor / BorderSizeProgressBarBase属性背景圆 / 主环 / 边框外观
Text / Font / ForeColorControl属性中央文字
Size / ClientSizeControl属性(Size)建议保持正方形;否则只绘制居中的正圆
Invalidate()Control方法触发重绘
OnPaint(e)本类(override)方法(protected)绘制逻辑,外部不可直接调用

事件(如 Change / ValueChanged)请参考 ProgressBarBase。


七、绘制原理(深入理解)

以下分析帮你在调整尺寸、环厚、边框、进度范围时理解 ProgressBarF 的具体表现。

7.1 计算外圆

float side = Math.Min(ClientSize.Width, ClientSize.Height);
if (side <= 4) return;

float d = side - 1f;                          // 直径,减 1 防描边被裁
float ox = (ClientSize.Width - d) / 2f;       // 水平居中
float oy = (ClientSize.Height - d) / 2f;      // 垂直居中
var outer = new RectangleF(ox, oy, d, d);
要点说明
min(宽, 高)无论控件是否正方形,都绘制正圆;非正方形时多出的空间留白
d = side - 1fGDI+ 抗锯齿下,直径等于 side 时最右/下边缘会被裁半像素,减 1 保证完整
side ≤ 4控件过小时直接不绘制,避免异常

7.2 主环厚度与路径矩形

float pw = Math.Min(this._pieWidth, d / 2f - 1f);
if (pw <= 0) return;

var arcRect = RectangleF.Inflate(outer, -pw / 2f, -pw / 2f);
要点说明
pw 上限 d/2 - 1Pen 是居中描边,半径最多 d/2。若 pw = d/2,内圆半径为 0(整块实心),不美观。限制到 d/2 - 1 保留内圆
arcRect = outer 内缩 pw/2Pen 居中描边时,外边缘会超出路径 pw/2。内缩 pw/2 后,主环外边缘正好贴到 outer 边界

7.3 绘制背景圆

using (var brush = new SolidBrush(this.ColorBack))
    g.FillPie(brush, outer.X, outer.Y, outer.Width, outer.Height, -90f, 360f);

用 FillPie(360°)而不是 FillEllipse,与进度弧走同一条 GDI+ 弧线路径族,抗锯齿边缘像素级重合,避免露出背景缝。绘制在 outer(而不是 arcRect)上,因为背景圆需要铺满整个外圆。

7.4 绘制装饰内环

if (this._showInnerRing)
{
    float innerOffset = pw + 6f;
    if (d - innerOffset * 2 > 10)
    {
        using (var pen = new Pen(this.ColorCore, 2f))
        {
            var penRect = RectangleF.Inflate(outer, -innerOffset, -innerOffset);
            g.DrawEllipse(pen, penRect);
        }
    }
}
要点说明
innerOffset = pw + 6f内环半径相对外圆半径的偏移量 = 主环厚度 + 6px 间距,保证内环在主环内侧且留出空档
d - innerOffset * 2 > 10内环直径 = d - innerOffset × 2。若 ≤ 10px,则不绘制,防止内环缩成一点
固定 2px 宽内环是装饰线,宽度不通过属性开放;固定 2px,用主色 ColorCore
outer 内缩 innerOffset绘制直径 = d - innerOffset × 2 的圆环,圆心与外圆一致

7.5 绘制进度弧

float sweep = 0f;
if (this.Max > this.Min)
{
    int v = Math.Max(this.Min, Math.Min(this.Max, this.Value));
    sweep = 360f * (v - this.Min) / (this.Max - this.Min);
}

if (sweep > 0f)
{
    using (var pen = new Pen(this.ColorCore, pw) { StartCap = LineCap.Flat, EndCap = LineCap.Flat })
        g.DrawArc(pen, arcRect, -90f, sweep);
}
要点说明
Max > Min 保护避免除零
Math.Max / Math.Min先把 Value clamp 到 [Min, Max],防止越界导致角度 > 360 或 < 0
360 × (v - Min) / (Max - Min)线性映射:v = Min → 0°;v = Max → 360°
StartCap / EndCap = Flat平头端点,让弧线两端是直线切口,视觉上不带“圆头”装饰,更干净
-90f从 12 点方向开始(GDI+ 0° 在 3 点方向,顺时针为正)
arcRect(已内缩 pw/2)配合 Pen 居中描边,外边缘贴合 outer

7.6 绘制文字与边框

if (!string.IsNullOrEmpty(this.Text))
{
    using (var brush = new SolidBrush(this.ForeColor))
    using (var sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center })
        g.DrawString(this.Text, this.Font, brush, outer, sf);
}

int border = Math.Min(this.BorderSize, (int)(d / 2) - 1);
if (border > 0)
{
    float half = border / 2f;
    var penRect = RectangleF.Inflate(outer, -half, -half);
    using (var pen = new Pen(this.BorderColor, border))
        g.DrawEllipse(pen, penRect);
}
要点说明
文字绘制在 outer 内居中于圆的正中心
border = min(BorderSize, d/2 - 1)边框半径不超过圆半径
penRect = outer 内缩 half同 arcRect 逻辑:Pen 居中描边,内缩一半线宽让外边缘贴到 outer
边框最后画覆盖在最外层,视觉上把内容“包”在圆内

八、完整使用示例

示例 1:基础圆环进度条

using System.Drawing;
using System.Windows.Forms;
using CConUI;

var bar = new ProgressBarF
{
    Parent = panel1,
    Location = new Point(20, 20),
    Min = 0,
    Max = 100,
    Value = 45,
    Text = "45%",
    ColorBack = Color.FromArgb(45, 45, 48),
    ColorCore = Color.FromArgb(0, 200, 120),
    BorderColor = Color.FromArgb(30, 30, 30),
    BorderSize = 2,
    PieWidth = 20,
    ShowInnerRing = true,
    ForeColor = Color.White,
    Font = new Font("Microsoft YaHei", 10F, FontStyle.Bold)
};

示例 2:配合计时器动态更新

var bar = new ProgressBarF
{
    Parent = this,
    Min = 0,
    Max = 100,
    Value = 0,
    Text = "0%",
    ColorBack = Color.FromArgb(50, 50, 50),
    ColorCore = Color.OrangeRed,
    BorderColor = Color.FromArgb(20, 20, 20),
    BorderSize = 3,
    PieWidth = 16,
    ShowInnerRing = false,
    Font = new Font("Segoe UI", 11F, FontStyle.Bold)
};

var timer = new Timer { Interval = 50 };
timer.Tick += (s, e) =>
{
    if (bar.Value >= bar.Max)
    {
        timer.Stop();
        bar.Text = "完成";
        return;
    }
    bar.Value += 1;
    bar.Text = bar.Value + "%";
    bar.Invalidate();   // 若基类 Value 不自动刷新,需要手动 Invalidate
};
timer.Start();

示例 3:隐藏内环(简洁风格)

var bar = new ProgressBarF
{
    Parent = this,
    Size = new Size(120, 120),
    Max = 100,
    Value = 70,
    PieWidth = 10,
    ShowInnerRing = false,          // 只显示一圈细弧
    ColorCore = Color.LimeGreen,
    ColorBack = Color.FromArgb(30, 30, 30)
};

示例 4:粗环 + 装饰内环(仪表盘风格)

var bar = new ProgressBarF
{
    Parent = this,
    Size = new Size(180, 180),
    Max = 100,
    Value = 82,
    Text = "82%",
    PieWidth = 26,
    ShowInnerRing = true,
    ColorCore = Color.FromArgb(0, 200, 255),
    ColorBack = Color.FromArgb(40, 40, 44),
    BorderColor = Color.FromArgb(20, 20, 20),
    BorderSize = 2,
    ForeColor = Color.White,
    Font = new Font("Consolas", 14F, FontStyle.Bold)
};

示例 5:非正方形控件(自动绘制正圆)

// 即使控件是长方形,圆环仍是正圆,周围留白
var bar = new ProgressBarF
{
    Parent = this,
    Size = new Size(300, 120),      // 实际圆直径 = min(300, 120) - 1 = 119
    Max = 100,
    Value = 60,
    PieWidth = 14,
    ColorCore = Color.DodgerBlue
};




转载请注明出处。

本文链接:http://www.pythonopen.com/?id=2

相关文章

已经实现的一些算法

编码CConA1是一种可复原的编码算法,用于将文本或字节转换为纯字母。可用于文件名混淆,避免因包含违...

横向滚动条HScrollBar 控件调用文档

命名空间:CConUI继承:System.Windows.Forms.Control版本:基于所提供...

纵向滚动条VScrollBar 控件调用文档

命名空间:CConUI继承:System.Windows.Forms.Control版本:基于所提供...

菜单MenuItem 与 ContextMenu 控件调用文档

命名空间:CConUI依赖:System.Windows.Forms、System.Drawing、...

图片框PictureBox 控件调用文档

命名空间:CConUI继承:System.Windows.Forms.Control定位:自绘图片框...

蚂蚁线AntLine 控件调用文档

命名空间:CConUI继承:System.Windows.Forms.Control定位:虚线蚂蚁线...