基于C#实现平滑进度条,通过设置ProgressBar的Style属性区分场景:无法确定时长时采用Marquee跑马灯模式;已知时长时利用Task.Run后台异步计算百分比,每100毫秒刷新Value值,结合this.Invoke委托更新UI,避免界面卡顿。
进度条在开发中几乎每天都会用到——文件下载、数据处理、批量操作,但凡需要等待的场景,总得有个元素告诉用户“别急,还在运行”。WinForm自带的ProgressBar控件,拖入即可使用,但要想实现流畅顺滑、不卡顿的显示效果,仍需要掌握一些关键技巧。本文将详细拆解这些实现细节。
从工具箱中将ProgressBar拖拽到窗体即可。如需更专业的界面布局,也可以将其放置在状态栏(statusStrip)中,与状态文字配合使用,视觉效果更为紧凑。
长期稳定更新的攒劲资源: >>>点此立即查看<<<

控件放置完成后,属性面板中提供多项配置。以下属性最为关键,直接决定进度条的表现方式。

| 属性 | 作用 |
|---|---|
| Minimum | 最小值(默认 0) |
| Maximum | 最大值(默认 100) |
| Value | 当前进度值(必须在 Min~Max 之间) |
| Style | 样式:Blocks(块状)/Continuous(连续)/Marquee(跑马灯,未知进度) |
| Enabled | 是否启用/禁用控件(True/False) |
| Visible | 是否显示/隐藏控件(True/False) |
进度条的核心在于Style属性。三种模式:Blocks(块状)、Continuous(连续)、Marquee(跑马灯)。选择哪种模式,取决于对任务时长的掌握程度。
如果任务总时长无法确定,或仅需临时界面占位,使用Marquee模式最为省心。跑马灯会持续循环滚动,直到将其隐藏。控制逻辑简单:任务开始时显示,任务结束时隐藏。
//状态枚举
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;
}
}
如果能估算出任务总时长(即使不够精确),即可使用精确的百分比进度。以下代码将总时长作为参数传入,后台异步计算进度,每100毫秒刷新一次,运行效果平滑流畅。
timer_Finish.Interval(总时长,单位毫秒)传入。Task.Run启动,不阻塞UI线程。refreshInterval默认100ms,总时长10秒可刷新100次,1秒也可刷新10次,完全满足需求。ProgressBar.Value显示,也可同时在状态栏显示文字。///
///开始和结束
///
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;
}
}
///
/// 按时间比例自动计算进度
///
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);
}
}
Value控制;未知进度,使用Marquee跑马灯模式。Task配合this.Invoke()委托,后台线程负责计算,UI线程只负责显示,界面不会卡死。侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述