ProgressBarA 进度条控件调用文档
命名空间:CConUI
继承:System.Windows.Forms.Control
可见性:public class ProgressBarA(可外部使用)
默认尺寸:180 × 24
默认事件:ValueChanged(设计器双击控件即生成该事件处理器)
定位:横向进度条——自绘轨道 + 进度填充;支持两种形状模式(纯矩形 / 右侧带半圆),并内置两种“等待特效”(跑马灯 / 反弹)动画。
一、作用
一个完全自绘的横向进度条,可用于:
按
Min ~ Max区间显示进度Value;通过
LoadStart() / LoadPause() / LoadEnd()开启“等待特效”:
跑马灯模式:滑块从左侧滑入、滑出右侧,再从左侧滑入,循环往复;
反弹模式:滑块在轨道内左右来回弹跳;两种形状:
Mode = One→ 纯矩形;Mode = Two→ 左侧平齐、右侧带半圆(“胶囊”风格);在控件中央绘制文字
Text(例如“45%”“正在加载…”);自定义边框粗细/颜色、背景色、进度色、字体、文字颜色。
视觉示意
| 状态 | 视觉 |
|---|---|
| 正常进度(Mode=One) | 轨道底色 + 左侧起、长度与 Value 成正比的矩形填充 |
| 正常进度(Mode=Two) | 矩形填充,但右侧末端是一个半圆(胶囊风格) |
| 跑马灯(WaitMode=One) | 一段固定宽度的滑块从左侧滑入 → 滑出右侧 → 循环;Mode=Two 时滑块两端都是半圆 |
| 反弹(WaitMode=Two) | 滑块在轨道内左右来回弹跳,碰边折返 |
二、快速上手
using System.Drawing;
using System.Windows.Forms;
using CConUI;
// 1. 创建控件
var bar = new ProgressBarA();
// 2. 放入容器
bar.Parent = panel1;
bar.Dock = DockStyle.Top; // 常见做法:贴在顶部或底部
bar.Height = 24;
// 3. 设置范围与当前值
bar.Min = 0;
bar.Max = 100;
bar.Value = 45;
bar.Text = "45%";
// 4. 外观
bar.ColorBack = Color.FromArgb(30, 35, 41);
bar.ColorCore = Color.FromArgb(76, 154, 255);
bar.BorderColor = Color.FromArgb(74, 85, 99);
bar.BorderSize = 2;
bar.ForeColor = Color.White;
bar.Font = new Font("Microsoft YaHei", 9F);
// 5. 订阅值变化事件
bar.ValueChanged += (s, e) =>
{
var b = (ProgressBarA)s;
Console.WriteLine("当前进度:" + b.Value);
};
// 6. 需要等待特效时
bar.WaitMode = CConPlus.Enum.ModeTwo.One; // One=跑马灯,Two=反弹
bar.LoadTimerInterval = 20; // 帧间隔毫秒(≥10)
bar.LoadStart(); // 开始
// ... 业务完成时
// bar.LoadEnd();三、构造函数与生命周期
public ProgressBarA()
| 项目 | 说明 |
|---|---|
| 参数 | 无 |
| 作用 | 初始化进度条 |
| 实际行为 | ① 启用 UserPaint | AllPaintingInWmPaint | OptimizedDoubleBuffer | ResizeRedraw 样式;② 创建内部 Timer(Interval = 20)并挂接 Tick;③ 设置 Size = (180, 24);④ 设置 ForeColor = Color.FromArgb(250, 250, 250) |
| 默认尺寸 | 180 × 24 |
| 默认范围 | Min = 0、Max = 100、Value = 0 |
| 默认外观 | BorderSize = 2、BorderColor = (74,85,99)、ColorBack = (30,35,41)、ColorCore = (76,154,255) |
| 默认模式 | Mode = One(矩形)、WaitMode = One(跑马灯) |
| Timer 启动 | 构造时不会启动;需显式调用 LoadStart() |
Dispose(bool disposing)
| 项目 | 说明 |
|---|---|
| 可见性 | protected override(外部不可直接调用) |
| 行为 | 若 disposing == true,释放内部 Timer |
四、公开属性
4.1 数据 / 进度
public int Min
| 项目 | 说明 |
|---|---|
| 类型 | int |
| 默认 | 0 |
| Category | CCon |
| DefaultValue | 0 |
| 作用 | 进度下限;同时用作“填充宽度计算”的下限保护 |
| 约束 | 仅当 value <= Max 时才被接受;否则静默忽略(保持原值)。接受后还会 Math.Max(0, value),即不能为负数 |
| 联动 | 若 Value < Min,自动把 Value 拉到 Min;随后 Invalidate() |
bar.Min = 0; // OK bar.Min = -5; // 被 clamp 到 0 bar.Min = 200; // 若 Max=100,则被忽略(保持原值)
public int Max
| 项目 | 说明 |
|---|---|
| 类型 | int |
| 默认 | 100 |
| Category | CCon |
| DefaultValue | 100 |
| 作用 | 进度上限;参与“填充宽度比例”计算 Quotient = 内部长度 / Max |
| 约束 | 仅当 value > Min 时才被接受;否则静默忽略。必须保证 Max > 0——若 Max = 0 会触发除以 0,绘制异常 |
| 联动 | 若 Value > Max,自动把 Value 拉到 Max;随后 Invalidate() |
bar.Min = 0; bar.Max = 100; // OK bar.Max = 0; // 被忽略(0 不大于 Min=0) bar.Max = 500; // OK // ⚠ Max 必须 > 0,否则内部 GetQuotient() 除零 // 由于 Min 默认 0,Max 必须 > 0 才能被接受
public int Value
| 项目 | 说明 |
|---|---|
| 类型 | int |
| 默认 | 0 |
| Category | CCon |
| DefaultValue | 0 |
| 作用 | 当前进度;决定填充宽度 |
| 取值范围 | 赋值时会自动 Math.Max(Min, Math.Min(Max, value))——clamp 到 [Min, Max] |
| 副作用 | 若值有变化: ① 触发 ValueChanged(e 为 EventArgs.Empty);② Invalidate() 重绘 |
| 幂等 | 赋相同值直接返回,不触发事件、不重绘 |
bar.Min = 0; bar.Max = 100; bar.Value = 45; // OK,触发 ValueChanged bar.Value = 45; // 相同值,不触发 bar.Value = 500; // 自动 clamp 到 100 bar.Value = -10; // 自动 clamp 到 0
public int LoadTimerInterval
| 项目 | 说明 |
|---|---|
| 类型 | int(毫秒) |
| 默认 | 20 |
| Category | CCon |
| 作用 | 等待特效的 Timer 刷新间隔;数值越小越流畅,CPU 占用越高 |
| 取值范围 | Math.Max(10, value)——至少 10ms |
| 副作用 | 直接写入 _timer.Interval;若 Timer 正在运行,下次 Tick 即采用新间隔;不触发重绘 |
bar.LoadTimerInterval = 20; bar.LoadTimerInterval = 5; // 被 clamp 到 10 bar.LoadTimerInterval = 50; // 更慢
4.2 形状与等待模式
public CConPlus.Enum.ModeTwo Mode
| 项目 | 说明 |
|---|---|
| 类型 | CConPlus.Enum.ModeTwo(One / Two) |
| 默认 | One |
| Category | CCon |
| DefaultValue | ModeTwo.One |
| 作用 | 进度条绘制的形状:One = 纯矩形;Two = 左侧平齐、右侧带半圆(胶囊末端) |
| 副作用 | 赋值后若值变化 Invalidate();值不变直接返回 |
| 备注 | 在等待特效下,Two 模式会让滑块的左右两端都是半圆(不再是“单侧胶囊”) |
bar.Mode = ModeTwo.One; // 矩形 bar.Mode = ModeTwo.Two; // 右侧(或两端)带半圆
public CConPlus.Enum.ModeTwo WaitMode
| 项目 | 说明 |
|---|---|
| 类型 | CConPlus.Enum.ModeTwo(One / Two) |
| 默认 | One |
| Category | CCon |
| DefaultValue | ModeTwo.One |
| 作用 | 等待特效的运行方式:One = 跑马灯(右侧滑出,左侧滑入,循环);Two = 反弹(碰到左右边界折返) |
| 副作用 | 赋值后 Invalidate() |
| 备注 | LoadStart() 时会根据当前 WaitMode 修正 _index 与 _bounceDirection,保证平滑 |
bar.WaitMode = ModeTwo.One; // 跑马灯 bar.WaitMode = ModeTwo.Two; // 反弹
4.3 颜色与外观
public Color ColorBack
| 项目 | 说明 |
|---|---|
| 类型 | Color |
| 默认 | Color.FromArgb(30, 35, 41) |
| Category | CCon |
| 作用 | 轨道(背景)填充色;绘制在边框内侧 |
public Color ColorCore
| 项目 | 说明 |
|---|---|
| 类型 | Color |
| 默认 | Color.FromArgb(76, 154, 255) |
| Category | CCon |
| 作用 | 进度填充色 / 等待滑块色 |
public Color BorderColor
| 项目 | 说明 |
|---|---|
| 类型 | Color |
| 默认 | Color.FromArgb(74, 85, 99) |
| Category | CCon |
| 作用 | 边框颜色 |
public int BorderSize
| 项目 | 说明 |
|---|---|
| 类型 | int(像素) |
| 默认 | 2 |
| Category | CCon |
| DefaultValue | 2 |
| 作用 | 边框粗细;为 0 时不绘制边框,轨道铺满整块控件 |
| 取值范围 | Math.Max(0, value)——不能为负数 |
| 副作用 | 赋值后 Invalidate() 重绘 |
4.4 重写的 Control 属性
public override string Text
| 项目 | 说明 |
|---|---|
| 类型 | string |
| Category | CCon |
| 作用 | 控件中央显示的文字;空串不绘制 |
| 副作用 | 赋值后 Invalidate() 重绘 |
public override Color ForeColor
| 项目 | 说明 |
|---|---|
| 类型 | Color |
| 默认 | Color.FromArgb(250, 250, 250)(构造时设置) |
| Category | CCon |
| 作用 | 文字颜色 |
public override Font Font
| 项目 | 说明 |
|---|---|
| 类型 | Font |
| Category | CCon |
| 作用 | 文字字体 |
五、公开事件
public event EventHandler ValueChanged
| 项目 | 说明 |
|---|---|
| 参数 | EventHandler:sender 为当前 ProgressBarA,e 为 EventArgs.Empty |
| Category | CCon |
| 默认事件 | 是([DefaultEvent("ValueChanged")]) |
| 触发时机 | Value 属性发生实际变化后 |
| 不触发情况 | ① 赋相同值(clamp 后与当前相同);② Min / Max 调整导致 Value 被主动修正——此时直接写 _value,不触发事件 |
| 触发顺序 | 先更新 _value → 触发 ValueChanged → Invalidate() |
bar.ValueChanged += (s, e) =>
{
var b = (ProgressBarA)s;
b.Text = b.Value + " / " + b.Max;
};六、公开方法
public void LoadStart()
| 项目 | 说明 |
|---|---|
| 参数 | 无 |
| 返回 | void |
| 作用 | 启动等待特效:开启内部 Timer,滑块开始运动 |
| 内部处理 | ① 若 Timer 已在运行,直接返回(幂等); ② WaitMode = One:若上次已滑出右侧(_index ≥ 轨道长 + 半径),重置到 -滑块宽 - 半径(从左侧外平滑切入);③ WaitMode = Two:把 _index 夹到 [0, 轨道长 - 滑块宽],并重置方向为向右;④ 启动 Timer |
bar.WaitMode = ModeTwo.One; bar.LoadStart(); // 开始跑马灯
public void LoadPause()
| 项目 | 说明 |
|---|---|
| 参数 | 无 |
| 返回 | void |
| 作用 | 暂停等待特效:停止 Timer,保留当前滑块位置 |
| 恢复 | 再次 LoadStart() 会从暂停位置继续 |
bar.LoadPause();
public void LoadEnd()
| 项目 | 说明 |
|---|---|
| 参数 | 无 |
| 返回 | void |
| 作用 | 结束等待特效:停止 Timer,并把 _index 重置为 0、_bounceDirection 重置为 1,然后 Invalidate() |
| 恢复 | 再次 LoadStart() 会从头开始(不会保留之前的位置) |
bar.LoadEnd();
public bool LoadEnabled()
| 项目 | 说明 |
|---|---|
| 参数 | 无 |
| 返回 | bool:true 表示等待特效正在运行(Timer 已启动) |
| 作用 | 查询当前是否处于等待特效状态 |
if (bar.LoadEnabled())
{
Console.WriteLine("正在等待特效中");
}七、公开成员速查表
| 成员 | 来源 | 类型 | 说明 |
|---|---|---|---|
ProgressBarA() | 本类 | 构造函数 | 180×24,默认 Timer 间隔 20ms |
Min | 本类 | 属性(int) | 进度下限(≥0;需 ≤ Max) |
Max | 本类 | 属性(int) | 进度上限(需 > Min;必须 > 0) |
Value | 本类 | 属性(int) | 当前进度;赋值自动 clamp 并触发 ValueChanged |
LoadTimerInterval | 本类 | 属性(int) | 等待特效间隔(毫秒,≥10) |
Mode | 本类 | 属性(ModeTwo) | 形状模式:One=矩形,Two=带半圆 |
WaitMode | 本类 | 属性(ModeTwo) | 等待模式:One=跑马灯,Two=反弹 |
ColorBack | 本类 | 属性(Color) | 轨道底色 |
ColorCore | 本类 | 属性(Color) | 进度色 / 等待滑块色 |
BorderColor | 本类 | 属性(Color) | 边框颜色 |
BorderSize | 本类 | 属性(int) | 边框粗细(≥0) |
Text(重写) | Control | 属性(string) | 中央文字 |
ForeColor(重写) | Control | 属性(Color) | 文字颜色 |
Font(重写) | Control | 属性(Font) | 文字字体 |
Size / ClientSize | Control | 属性(Size) | 控件尺寸;高度决定半圆半径 |
ValueChanged | 本类 | 事件(默认事件) | Value 变化后触发 |
LoadStart() | 本类 | 方法 | 开始等待特效 |
LoadPause() | 本类 | 方法 | 暂停等待特效(保留位置) |
LoadEnd() | 本类 | 方法 | 结束等待特效(重置位置) |
LoadEnabled() | 本类 | 方法 | 查询等待特效是否运行中 |
Invalidate() | Control | 方法 | 触发重绘 |
OnPaint(e) | 本类(override) | 方法(protected) | 绘制逻辑,外部不可直接调用 |
Timer_Tick | 本类 | 方法(private) | 等待特效每帧推进,外部不可直接调用 |
GetFillWidth / GetQuotient / GetInternalLength / GetRadius / GetLoadSliderWidth | 本类 | 方法(private) | 内部计算辅助 |
Dispose | 本类(override) | 方法(protected) | 释放 Timer |
八、绘制与动画原理(深入理解)
8.1 关键内部量与公式
| 内部量 | 计算 | 作用 |
|---|---|---|
GetInternalLength() | max(0, Width - BorderSize × 2) | 边框内可绘制区域的总宽度(像素) |
GetQuotient() | GetInternalLength() / Max | “每 1 个进度单位”对应多少像素。 为什么除以 Max:把内部宽度按 Max 均分;Value = Max 时宽度 = 内部宽度,即铺满 |
GetFillWidth() | GetQuotient() × max(Value, Min) | 正常进度的填充宽度。 为什么 max(Value, Min):保证不会比下限还短 |
GetRadius() | max(0, (Height - BorderSize × 2) / 2) | 半圆半径 = 内部高度的一半;Mode = Two 时用于绘制末端半圆 |
GetLoadSliderWidth() | 若 Value > 0:GetFillWidth();否则 max(20, 内部宽度 × 0.3) | 等待滑块宽度;Value = 0 时用默认 30% 宽,避免滑块变成 0 宽看不见 |
8.2 绘制顺序
绘制轨道底色:用
ColorBack在(BorderSize, BorderSize, W - 2×BorderSize, H - 2×BorderSize)矩形内填充;绘制进度 / 等待滑块:用
ColorCore填充;
先设置裁剪:g.SetClip(边框内侧矩形),保证内容不会超出轨道边界;
绘制完成后g.ResetClip();绘制边框:用
BorderColor / BorderSize;
Pen 居中描边,所以绘制矩形内缩BorderSize / 2,让边框外边缘贴到控件边缘;绘制文字:
Text在整块控件内居中(Center / Center)。
8.3 正常进度绘制
float fillW = (float)GetFillWidth();
if (fillW > 0)
{
// 矩形填充:从边框内侧左上角开始
g.FillRectangle(brush, bs, innerY, fillW, innerHeight);
if (Mode == ModeTwo.Two)
{
// 右侧半圆:圆心在矩形右端中心,半径 = innerHeight / 2
g.FillEllipse(brush, bs + fillW - radius, innerY, innerHeight, innerHeight);
}
}| 要点 | 说明 |
|---|---|
FillRectangle(bs, innerY, fillW, innerHeight) | bs = 边框粗细;从边框内侧开始填充,宽 fillW,高 = 内部高度 |
右侧半圆 FillEllipse(bs + fillW - radius, innerY, innerHeight, innerHeight) | 画一个直径 = 内部高度的圆,圆左边缘与矩形右端重叠 radius,视觉上形成“右端是半圆”的胶囊效果。为什么减 radius:圆心要在矩形右端的中点,画圆的 X 起点 = 圆心 X − 半径 = (bs + fillW) − radius |
8.4 等待特效绘制
int sliderWidth = GetLoadSliderWidth();
float loadX = bs + _index; // _index 可以为负 → 滑块从左侧外滑入
float loadW = sliderWidth;
g.FillRectangle(brush, loadX, innerY, loadW, innerHeight);
if (Mode == ModeTwo.Two)
{
g.FillEllipse(brush, loadX + loadW - radius, innerY, innerHeight, innerHeight); // 右侧半圆
g.FillEllipse(brush, loadX - radius, innerY, innerHeight, innerHeight); // 左侧半圆
}| 要点 | 说明 |
|---|---|
loadX = bs + _index | _index 是相对轨道左侧的偏移;可以为负(从左侧外滑入)也可以大于轨道长(滑出右侧) |
Mode = Two 时两端都加半圆 | 区别与正常进度:等待滑块是一个独立“胶囊块”,两端都应圆润,否则滑块看起来半圆半方 |
裁剪 SetClip | 即便 loadX 为负或过大,超出部分也会被裁剪,视觉上就是“平滑滑入 / 滑出” |
8.5 跑马灯模式(WaitMode=One)
if (_index >= trackLength + radius) _index = -sliderWidth - radius; // 滑出右侧后,重置到左侧外 else _index += step; // 正常前进
| 要点 | 说明 |
|---|---|
重置阈值 trackLength + radius | 当滑块左边缘超过 轨道长 + 半径 时,说明整个滑块(含右侧半圆)都已经滑出右边界;此时重置 |
重置值 -sliderWidth - radius | 让滑块完全在左侧外面:滑块左边缘 = -sliderWidth - radius,其右边缘 = -radius,右侧半圆恰好贴在左边界外,下一帧开始就会“从左侧钻出” |
step | max(1, (int)GetQuotient())——每帧前进约“1 个进度单位”对应的像素;有最小 1 像素兜底 |
8.6 反弹模式(WaitMode=Two)
_index += step * _bounceDirection;
if (_index <= 0)
{
_index = 0;
_bounceDirection = 1; // 向右
}
else if (_index + sliderWidth >= trackLength)
{
_index = max(0, trackLength - sliderWidth);
_bounceDirection = -1; // 向左
}| 要点 | 说明 |
|---|---|
| 位置更新 | _index += step × _bounceDirection——方向为 +1 向右、−1 向左 |
| 左边界 | _index ≤ 0 时贴到 0,方向改向右 |
| 右边界 | _index + sliderWidth ≥ trackLength 时贴到 trackLength - sliderWidth,方向改向左 |
| 滑块比轨道还宽时 | trackLength - sliderWidth 可能为负,用 Math.Max(0, ...) 兜底贴左 |
九、完整使用示例
示例 1:基础进度条
using System.Drawing;
using System.Windows.Forms;
using CConUI;
var bar = new ProgressBarA
{
Parent = this,
Dock = DockStyle.Top,
Height = 24,
Min = 0,
Max = 100,
Value = 0,
Text = "0%",
BorderSize = 2,
BorderColor = Color.FromArgb(74, 85, 99),
ColorBack = Color.FromArgb(30, 35, 41),
ColorCore = Color.FromArgb(76, 154, 255),
ForeColor = Color.White
};
bar.ValueChanged += (s, e) =>
{
var b = (ProgressBarA)s;
b.Text = b.Value + "%";
};
// 模拟加载
var t = new Timer { Interval = 50 };
t.Tick += (s, e) =>
{
if (bar.Value >= bar.Max) { t.Stop(); bar.Text = "完成"; return; }
bar.Value += 1;
};
t.Start();示例 2:胶囊形状(Mode = Two)
var bar = new ProgressBarA
{
Parent = this,
Dock = DockStyle.Top,
Height = 22,
Min = 0,
Max = 100,
Value = 60,
Mode = CConPlus.Enum.ModeTwo.Two, // 右侧带半圆
BorderSize = 0, // 无边框,胶囊效果更明显
ColorBack = Color.FromArgb(240, 240, 240),
ColorCore = Color.DodgerBlue
};示例 3:等待特效(跑马灯)
var bar = new ProgressBarA
{
Parent = this,
Dock = DockStyle.Top,
Height = 24,
Text = "正在加载…",
WaitMode = CConPlus.Enum.ModeTwo.One, // 跑马灯
Mode = CConPlus.Enum.ModeTwo.Two, // 滑块两端半圆
LoadTimerInterval = 20,
ColorCore = Color.Orange
};
bar.LoadStart(); // 开始示例 4:等待特效(反弹)
var bar = new ProgressBarA
{
Parent = this,
Dock = DockStyle.Top,
Height = 24,
Text = "处理中…",
WaitMode = CConPlus.Enum.ModeTwo.Two, // 反弹
Mode = CConPlus.Enum.ModeTwo.One,
LoadTimerInterval = 15,
BorderSize = 1,
ColorCore = Color.LimeGreen
};
bar.LoadStart();示例 5:可暂停 / 继续 / 结束的等待
var bar = new ProgressBarA
{
Parent = this,
Dock = DockStyle.Top,
Height = 24,
WaitMode = CConPlus.Enum.ModeTwo.One
};
btnPause.Click += (s, e) =>
{
if (bar.LoadEnabled())
{
bar.LoadPause();
btnPause.Text = "继续";
}
else
{
bar.LoadStart();
btnPause.Text = "暂停";
}
};
btnStop.Click += (s, e) =>
{
bar.LoadEnd();
bar.Text = "已停止";
};示例 6:从等待特效切回正常进度
var bar = new ProgressBarA { Parent = this, Dock = DockStyle.Top, Height = 24 };
bar.LoadStart();
bar.Text = "准备中…";
// 业务数据准备好后:
bar.LoadEnd(); // 结束等待,重置内部位置
bar.Min = 0;
bar.Max = 100;
bar.Value = 0;
bar.Text = "0%";
// 开始显示实际进度...十、注意事项
Max必须大于 0:由于Min默认 0,Max的 setter 里判断value > Min,且Min至少是 0,所以Max实际必须> 0才能生效。若被设成 0,绘制时GetQuotient()除 0 得到Infinity,填充宽度异常。Max不能小于Min:setter 里判断value > Min,否则静默忽略。因此改Max时要先保证Min不会比它大。Min不能为负数:setter 内部Math.Max(0, value)强制归零。如果你需要负数区间,这个控件做不到。Value会被自动 clamp 到[Min, Max]:赋值越界不会报错,但也不会按越界值绘制。Min/Max调整导致的Value修正不触发ValueChanged:这是本类与部分控件不同之处——只有当直接写Value且值变化时才触发。若业务依赖“任何变化都感知”,请在改Min/Max后手动比较并处理。设相同
Value不触发:setter 先做 clamp,再比较,如果与当前值相同直接返回。ValueChanged的e是EventArgs.Empty,不是null。可以正常用e,但通常用不到。等待特效时
Value不影响画面:OnPaint里优先判断LoadEnabled(),为true时绘制等待滑块,而不是按Value绘制进度。此时改Value画面不变,但仍会触发ValueChanged。等待滑块宽度与
Value有关:GetLoadSliderWidth()用GetFillWidth(),Value = 0时退回默认 30% 宽。
如果想控制滑块宽度,可在LoadStart()之前把Value设成一个合适的值,或修改源码。LoadStart会修正初始位置:跑马灯:若上次滑出右侧,会重置到左侧外——第一次
LoadStart时_index = 0,滑块从左侧边缘开始,不会“从外面平滑滑入”。如果要首次启动就平滑滑入,可以在启动前手动设置一个场景,或修改源码把初始_index设为负数。反弹:把位置夹回
[0, 轨道长 - 滑块宽]并重置方向为向右。LoadPause保留位置,LoadEnd重置位置:LoadPause()后再LoadStart():从暂停处继续;LoadEnd()后再LoadStart():从头开始。隐藏控件不会停止 Timer:本类未重写
OnVisibleChanged,Visible = false时等待特效仍在后台推进。不需要动画时请显式LoadPause()或LoadEnd()。Dispose 时会自动释放 Timer,无需手动
LoadEnd。但Dispose后若还持有引用并调用LoadStart,会抛ObjectDisposedException。非正方形尺寸下
Mode = Two的胶囊效果以内部高度为准:半圆直径 = 内部高度,因此控件越矮,末端半圆越扁;要得到标准胶囊效果,建议Height ≤ 30且不要太小。Mode = Two在等待特效下会让滑块两端都加半圆:与正常进度(仅右侧半圆)不同。如果希望等待时也只用右侧半圆,需要修改源码。文字总在控件正中央:绘制在
(0, 0, Width, Height)内居中,与进度填充无关。若担心文字被进度色块遮住,可调整ForeColor保证对比度。BorderSize = 0时无边框:轨道底色铺满整个客户区,视觉更简洁。Timer 的步长与
Max有关:step = max(1, (int)GetQuotient())。若Max很大、控件很窄(如Max = 1000、宽度 100),GetQuotient() < 1,step退化为 1 像素;若Max很小、宽度很大,step会很大,滑块会“跳跃式”移动。
想让动画更平滑,可以适当调大Max(让step变小),或减小控件宽度。当然更直接的方法是调小LoadTimerInterval。属性描述里的 Category 都是
CCon(不是CCon_数据等细分分类);如需更细分组,需修改源码中的[Category]。本类与
ProgressBarB/C/D/E/F是不同风格:ProgressBarA是横向条状;B/C/D/E/F是圆形/圆环。若要更换风格,请注意属性差异较大。
转载请注明出处。