目录
引言
- ProgressBar 是进度显示控件,核心作用是直观展示任务执行进度(如文件下载、数据处理、批量操作)。
- C# WinForm 中的 ProgressBar 是工具箱原生控件,简单易用,但是要做到平滑流畅控制,还有一些小技巧的,本文以最简单方式介绍给大家。
一、拖入控件
- 将工具栏中的ProgressBar,拖入到界面中。可以到界面中会出现新的控件,当然为了美观也可以拖到底部状态栏(statusStrip)中。

二、设置核心属性
- 添加控件后可以在属性中看到各种属性(如下图),表中列举的是最核心的属性项目。

| 属性 | 作用 |
|---|---|
| Minimum | 最小值(默认 0) |
| Maximum | 最大值(默认 100) |
| Value | 当前进度值(必须在 Min~Max 之间) |
| Style | 样式:Blocks(块状)/Continuous(连续)/Marquee(跑马灯,未知进度) |
| Enabled | 是否启用/禁用控件(True/False) |
| Visible | 是否显示/隐藏控件(True/False) |
,Blocks(块状)/Continuous(连续)/Marquee(跑马灯,未知进度)三种可选。
1、无法确认过程时长
- 如果我们的运行的过程的时间完全无法确认,不知道任务总时长,又或者是先摆上界面临时使用。那么可以先设置样式(Style)为Marquee,只要在开始和结束的时候分别控制Visible即可。
c
//状态枚举
public enum DEV_RUN_STATUS
{
Null,
Idle,
Starting,
Running,
Stoping,
}
RUNNING_STEP startRunningStep = RUNNING_STEP.Ready;//开始运行步骤变量,Ready
//初始化加载
private void Form_main_Load(object sender, EventArgs e)
{
progressBar.Style = ProgressBarStyle.Marquee;//指定样式
progressBar.MarqueeAnimationSpeed = 30; // 指定动画速度
}
private void btnControlStart_Click(object sender, EventArgs e)
{
if (startRunningStep == RUNNING_STEP.Ready)
{
//运行开始显示进度条
ProgressBar.Visbile = true;
}
else if (startRunningStep == RUNNING_STEP.Stoping)
{
//运行结束隐藏进度条
ProgressBar.Visbile = false;
}
}
2、可以获取运行时长
- 启动时,我们可以知道运行时间哪怕是不确定的,我们可以传递过来,入下面的时间就是timer_Finish.Interval。我们起一个任务,本质上也是启动了一个新的线程。
- 启动后调用了函数DoRealProgress()异步处理,不影响主线程。
- refreshInterval 是检查的间隔时间,当前每100ms刷新一次,如果总时长10秒,可以刷新1000次,1秒也能10次。当然也可以自行修改自定义。
- percent 是当前的运行时间百分比,ProgressBar.Value是当前显示的百分比,也可以将百分比以文字显示出来。
c
/// </summary>
///开始和结束
/// </summary>
private void btnControlStart_Click(object sender, EventArgs e)
{
if (startRunningStep == RUNNING_STEP.Ready)
{
//运行开始显示进度条
ProgressBar.Visbile = true;
//启用百分比文字显示
toolStripStatusLabel_percentage.Visible = true;
// 启动后台进度条任务,时间作为输入参数
Task.Run(() => DoRealProgress(timer_Finish.Interval));
}
else if (startRunningStep == RUNNING_STEP.Stoping)
{
//运行结束隐藏进度条
ProgressBar.Visbile = false;
//关闭百分比显示
toolStripStatusLabel_percentage.Visible = false;
}
}
/// <summary>
/// 按时间比例自动计算进度
/// </summary>
private async void DoRealProgress(int totalMs)
{
//读取开始时间作为分母
DateTime startTime = DateTime.Now;
// 每100ms刷新一次,比较平滑流畅
int refreshInterval = 100;
while (isStartRunning)
{
// 计算已用时间
double elapsedMs = (DateTime.Now - startTime).TotalMilliseconds;
// 计算百分比(0~100)读取当前时间除以开始时间获取百分比
int percent = (int)(elapsedMs / totalMs * 100);
// 防止超过100
percent = Math.Min(percent, 100);
// 委托更新UI
this.Invoke(new Action(() => {
//设置百分比
ProgressBar.Value = percent;
//文本显示百分比
toolStripStatusLabel_percentage.Text = $"{percent}%";
}));
//延时
await Task.Delay(refreshInterval);
}
}
总结
- 本文简单介绍了ProgressBar的基础功能和使用,并使用代码实现了平滑流畅的效果,非常实用。已知进度和时间用 Value 控制,未知进度用 Marquee 跑马灯;
- 注意WinForm 跨线程更新 UI 用到了Task任务和UI执行this.Invoke()委托,将任务必须放在后台线程,避免界面卡死,也同时简化了异步代码,可读性更高;
- 直接复制代码即可运行,适配绝大多数进度场景哦!