C# 实现平滑流畅的进度条ProgressBar

目录


引言

  • ProgressBar 是进度显示控件,核心作用是直观展示任务执行进度(如文件下载、数据处理、批量操作)。
  • C# WinForm 中的 ProgressBar 是工具箱原生控件,简单易用,但是要做到平滑流畅控制,还有一些小技巧的,本文以最简单方式介绍给大家。

一、拖入控件

  • 将工具栏中的ProgressBar,拖入到界面中。可以到界面中会出现新的控件,当然为了美观也可以拖到底部状态栏(statusStrip)中。

二、设置核心属性

  • 添加控件后可以在属性中看到各种属性(如下图),表中列举的是最核心的属性项目。
属性 作用
Minimum 最小值(默认 0)
Maximum 最大值(默认 100)
Value 当前进度值(必须在 Min~Max 之间)
Style 样式:Blocks(块状)/Continuous(连续)/Marquee(跑马灯,未知进度)
Enabled 是否启用/禁用控件(True/False)
Visible 是否显示/隐藏控件(True/False)

!属性界面(https://i-blog.csdnimg.cn/direct/f6ffb93f180347468547544c41cff7df.png-

三、 选择样式和构建代码

  • ProgressBar最先需要看的设置属性就是样式(Style),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()委托,将任务必须放在后台线程,避免界面卡死,也同时简化了异步代码,可读性更高;
  • 直接复制代码即可运行,适配绝大多数进度场景哦!
相关推荐
xiaoshuaishuai89 小时前
C# AvaloniaUI 资源找不到报错
java·服务器·前端·windows·c#
Xin_ye100869 小时前
C# 零基础到精通教程 - 第十八章:部署与发布——让应用上线
开发语言·c#
爱讲故事的10 小时前
操作系统第一讲复习:为什么学习操作系统,以及操作系统到底在做什么?
linux·开发语言·windows·学习·ubuntu·c#
JaydenAI11 小时前
[MAF预定义的AIContextProvider-03]ChatHistoryMemoryProvider——赋予Agent从经验中学习的能力
ai·c#·agent·memory·maf
z落落12 小时前
C# 继承:父子构造函数 + base 关键字 +五大访问修饰符(同项目+跨项目 全覆盖)
开发语言·c#
海盗123412 小时前
C#中PDF操作-QuestPDF页面设置与布局
java·pdf·c#
玩c#的小杜同学13 小时前
一周 AI 新鲜事|2026.05.25—2026.05.31
人工智能·程序人生·ai·c#·程序员创富
周杰伦fans13 小时前
C# 异常继承深度解析:从设计原则到 sealed 关键字的奥秘
java·jvm·c#
多巴胺耐受13 小时前
【WPF】炫酷的科技报警弹窗
科技·c#·wpf