在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. openSuSE12.1 zypper LAMP

    LAMP是由Apache MySQL PHP组成的,是在Linux下最受欢迎的软件组合之一,目前互联网上有很多网站运行在LAMP服务器上. Linux - 是富有情味的开源操作系统:Apache -  ...

  2. 在线App开发平台——应用之星傻瓜式开发平台

    随着智能手机及APP应用程序的普及,越来越多的企业和个人意识到APP的营销价值,出于对技术的敬畏,很多企业下意识认为开发APP是一个有难度的技术活,所以很多时候有心无力,也担心APP的后续的技术支持. ...

  3. btrace 笔记

    转载请注明原链接地址 http://www.cnblogs.com/dongxiao-yang/p/6134393.html btrace 是一个可以不用重启线上java业务查问题的神器,记一下自己折 ...

  4. 创业公司求IOS、Android攻城狮一枚

    地点:北京CBD附近(地铁1号线大望路) 魅力值:送珍贵期权 你要会:       1. IOS或者Android开发       2.可以处理类似微视/秒拍的视频录制功能       3.熟悉jso ...

  5. java程序员从笨鸟到菜鸟系列

    http://blog.csdn.net/csh624366188/article/category/888600

  6. 使用tuple返回多个值

    17.4编写并测试findbook函数 #include<iostream> #include<vector> #include<string> #include& ...

  7. 解析嵌套json字符串,一个json字符串中嵌套另一个json字符串

    我现在有一个字符串是这样: { "msg": { ", "attrName": "sensorData", "trans ...

  8. 多维数组遍历PHP

    原文出处 <?php /* * ------------------------------------------------- * Author : nowamagic * Url : ww ...

  9. PHP 数组转字符串,与字符串转数组

    implode 使用一个字符串将数组变成字符串 <?php $array = array('lastname', 'email', 'phone'); $comma_separated = im ...

  10. Error parsing XML: not well-formed (invalid token)

    从网络上或别的文件复制粘贴进来的代码有隐含格式,可将内容先粘贴进记事本清除格式,再复制粘贴进工程文件,即可解决此问题 注:1. 要使工程文件全选清空, 2. 若粘贴后刷新仍无效果,可手动输入