在WinForm程序中,大多数情况下我们是知道程序运行所需要的时间或步骤的,比如批量复制文件时文件的数量,数据导出或导入时数据的总行数等等。对于步骤比较确定的操作,如果程序执行过程时间较长,很容易使用BackgroundWorker结合ProgressBar来显示一个实时的进度。相关内容大家可以看我博客中的其它文章,有关如何使用BackgroundWorker和ProgressBar。但是,有的时候我们是不确定程序执行的具体步骤或时长的,比如连接一个远程服务或数据库服务,或者调用一个远程过程或WebService等,这个时候我们就没有办法去触发BackgroundWorker的ProgressChanged事件,因此也就不能实时去更新ProgressBar的进度了。有两种替代的办法可以解决这个问题。

第一是将ProgressBar的Style设置为Marquee而不是默认的Blocks。在Marquee模式下,进度条会不停地向前走用来模拟一个长时间的操作。事实上,Windows中也有很多类似的进度条,大多都是出现在对操作过程所需的步骤和时长不太确定的时候。这种方法很简单,不过你仍然要将后台的执行过程放到多线程来执行,否则进度条会卡在UI线程中。一个好的办法就是依旧使用BackgroundWorker组建,将后台的执行程序放到BackgroundWorker的DoWorker事件中,然后调用BackgroundWorker的RunWorkerAsync方法来异步执行程序。这样,UI线程和后台执行程序的线程可以分开,进度条便不会再卡了。

第二种方法是使用System.Windows.Forms.Timer定时器控件,设置好Timer的Interval间隔时间,在Timer的Tick事件中来更新ProgressBar的进度。由于Timer天生就是多线程的,所以这种办法实现起来很方便。

using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Data;
 using System.Drawing;
 using System.Linq;
 using System.Text;
 using System.Windows.Forms;
 using System.Threading;
 
 namespace WindowsFormsApplication2
 {
     public partial class Form1 : Form
     {
         private BackgroundWorker worker = new BackgroundWorker();
         private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

public Form1()
         {
             InitializeComponent();
             this.progressBar1.Value = 0;
             this.progressBar1.Maximum = 200;
             this.progressBar1.Step = 1;
             timer.Interval = 100;
             timer.Tick += new EventHandler(timer_Tick);
             worker.WorkerReportsProgress = true;
             worker.DoWork += new DoWorkEventHandler(worker_DoWork);
             worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
             worker.RunWorkerAsync();
             timer.Start();
         }

void timer_Tick(object sender, EventArgs e)
         {
             if (this.progressBar1.Value < this.progressBar1.Maximum)
             {
                 this.progressBar1.PerformStep();
             }
         }

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
         {
             timer.Stop();
             this.progressBar1.Value = this.progressBar1.Maximum;
             MessageBox.Show("Complete!");
         }

void worker_DoWork(object sender, DoWorkEventArgs e)
         {
             int count = 100;
             for (int i = 0; i < count; i++)
             {
                 Thread.Sleep(100);
             }
         }
     }
 }   Timer每隔100毫秒便调用一次Tick事件,在该事件中更新ProgressBar的当前进度。注意需要判断ProgressBar的Value必须小于Maximum值时才去执行Performance()方法,否则会出现ProgressBar的Value大于Maximum的值而抛异常。根据BackgroundWorker的DoWork方法执行所需的时间长短不同,ProgressBar的进度可能会在BackgroundWorker执行具体操作完成之前到达100%,也可以没有到达100%,所以在BackgroundWorker的RunWorkerCompleted事件中将ProgressBar的进度更新为100%,以确保进度在最后是一个完成的状态。

如果你在应用程序中确实需要使用进度条来提示用户后台程序在完成一个耗时较长的操作,而且你还希望进度条能尽量模拟出程序执行的步骤,而不是一个Marquee状态,可以考虑使用Timer定时器控件。因为,有的时候我们确实很难评估一个执行过程到底需要多少步骤或者需要多长时间才能完成。

WinFrom ProgressBar控件的使用的更多相关文章

  1. winFrom 常用控件属性及方法介绍

    目录 1.窗体(Form) 2.Label (标签)控件 3.TextBox(文本框)控件 4.RichTextBox控件 5.NumericUpDown控件 6.Button(按钮)控件 7.Gro ...

  2. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.9.Progressbar控件

    Progressbar控件用来显示任意进程的完成百分比. 默认安装启用 配置选项 控件暴露的事件API progressbar暴露的独一无二的方法 一些现实生活的例子 当前版本中,我们或系统必须明确进 ...

  3. 分享一个漂亮的ProgressBar控件

    codeprject上看到的一个漂亮的ProgressBar控件.是用vb.net开发的. C#直接在工具箱中引用即可. 地址:http://www.codeproject.com/Articles/ ...

  4. C#在WinForm中重写ProgressBar控件(带%的显示)

    废话少说,直接上码: namespace csPublish { [ToolboxItem(true)] class textProgressBar : System.Windows.Forms.Pr ...

  5. 在ProgressBar控件中显示进度百分比

    实现效果: 知识运用: ProgressBar控件的Value属性 //控件的当前值 Maximum属性 //ProgressBar正在使用的范围的上限 PerformStep方法 //按照Step属 ...

  6. C# 根据BackgroundWoker异步模型和ProgressBar控件,自定义进度条控件

    前言 程序开发过程中,难免会有的业务逻辑,或者算法之类产生让人能够感知的耗时操作,例如循环中对复杂逻辑处理;获取数据库百万乃至千万级数据;http请求的时候等...... 用户在使用UI操作并不知道程 ...

  7. android:ProgressBar控件

    ProgressBar 用于在界面上显示一个进度条,表示我们的程序正在加载一些数据.它的用 法也非常简单,修改 activity_main.xml 中的代码,如下所示: <LinearLayou ...

  8. WinFrom 公共控件 Listview 的使用

    Listview绑定数据库数据展示与操作使用  1.拖一个Listview控件到项目中先将视图改为Details 2.编辑列 设置列头  添加columnHeader成员 Text 是显示的名称 3. ...

  9. 野比的示波器案例(Winfrom用户控件)

    使用该用户控件做的效果图,如果数据正确,可实现 波形.直线.等等效果图...... 对于本程序的认识还是不够深彻.如果有其他方法或算法,欢迎讨论下.将我所能理解的代码都再次标识了一番. ------- ...

随机推荐

  1. 前端自动生成/加载CSS

    前言: 1.我很懒! 2.写样式时,很多时候需要单独设置长度.宽度.内间距.外间距等.于是,就会有很多CSS代码会出现很多类似以下的代码: .w20: { width: 20px; } .mt10: ...

  2. 日常使用 Git 的 19 个建议

    如果你对git一无所知,那么我建议先去读一下Git 常用命令速查.本篇文章主要适合有一定 git 使用基础的人群. 目录: 日志输出参数 查看文件的详细变更 查看文件中指定位置的变更 查看尚未合并(m ...

  3. seq命令

    seq 5 seq 5 >1.txt 其中的>是覆盖 seq 1 5 用来产生从数1到数5之间的所有整数 或, seq 5

  4. Caffe 在 Ubuntu 中安装

    Ubuntu Installation General dependencies sudo apt-get install libprotobuf-dev libleveldb-dev libsnap ...

  5. 329. Longest Increasing Path in a Matrix

    最后更新 三刷? 找矩阵里的最长路径. 看起来是DFS,实际上也就是.但是如果从每个点都进行一次DFS然后保留最大的话,会超时. 这里需要结合DP,dp[i][j]表示以此点开始的最长路径,这样每次碰 ...

  6. jsp 多条记录提交

    前端jsp页面可以通过form提交标有name属性值得input的value数据给服务器,其中如何传递数组形式呢?如下: 1.前端jsp页面 其中灰色的部分是一个循环出现的值,因此form提交后,后台 ...

  7. sql server2008报“评估已过期....."

    开始-->所有程序-->Microsoft SQL Server 2008-->配置工具-->SQL Server 安装中心-->维护-->版本升级,接着按照提示一 ...

  8. postgresql9.4新特性jsonb学习-update更新操作

    先科普下概念:PgSQL9.4 新增 JSONB 数据类型, JSONB 同时属于 JSON (JavaScript Object Notation) 数据类型,jsonb 和 json 的输入数据几 ...

  9. 兔子--R.java丢失原因及解决的方法

    R.jar丢失原因: a:eclipse指向的adk路径有中文,或者是workspace路径有中文 b:xml文件里有错误或者引用的资源不存在 c:xml或者drawable下资源文件不能够有大写字母 ...

  10. Linux系统下UDP发送和接收广播消息小样例

    [cpp] view plaincopy // 发送端 #include <iostream> #include <stdio.h> #include <sys/sock ...