在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. It appears as though you do not have permission to view information for any of the services you requested

  2. jQuery的文档操作方法

    jQuery 文档操作方法 这些方法对于 XML 文档和 HTML 文档均是适用的,除了:html(). 方法 描述 addClass() 向匹配的元素添加指定的类名. after() 在匹配的元素之 ...

  3. codeforces 714C解题报告

    http://codeforces.com/contest/714/problem/C #include <bits/stdc++.h>//非递归形式建立字典树 using namespa ...

  4. 制作一个html中闪动的title 来提示消息

    var flashTitlePlayer = { start: function (msg) { this.title = document.title; if (!this.action) { tr ...

  5. IO 流—>>>补充

    流操作规律: 示例:1. 源: 键盘录入 目的: 控制台 2.源:文件 目的:控制台 3.源: 键盘录入 目的: 文件 基本规律: 面对流对象很多,不知道用哪一个的时候: 通过两个明确来完成 1.明确 ...

  6. PHP开发APP接口(一)

    php以json或者xml 形式返回给app.明白这点就很好说了,就是把数据包装成json或者xml,返回给APP 定义抽象APP基类: <?php /** * 定义API抽象类 */ abst ...

  7. String+,StringBuilder,String.format运行效率比较

    实现String字符串相加的方法有很多,常见的有直接相加,StringBuilder.append和String.format,这三者的运行效率是有差异的,String是final类型的,每次相加都会 ...

  8. mysql查询随机几条数据(速度快)

    MySql查询随机几条数据 想到了 Max RAND 这几个函数 用以下2种办法都可以实现查询. 速度还行. 几十万数据左右, 没有什么问题. SELECT * FROM `news` WHERE i ...

  9. poj 1149 Pigs 网络流-最大流 建图的题目(明天更新)-已更新

    题目大意:是有M个猪圈,N个顾客,顾客要买猪,神奇的是顾客有一些猪圈的钥匙而主人MIRKO却没有钥匙,多么神奇?顾客可以在打开的猪圈购买任意数量的猪,只要猪圈里有足够数量的猪.而且当顾客打开猪圈后mi ...

  10. cocos2d-x 3.0正式版 环境搭建 (解决载入失败,未能载入XXX包)

    cocos2d-x 3.0正式版最终公布了~ 等了好久~ 废话不多说,直接写方法. 1.下载安装vc2012 ,我用的是旗舰版,传送门:点击打开链接 2.下载cocos2d-x 3.0正式版,传送门: ...