场景在Winform中实现弹窗式进度条
就是新建一个窗体,然后在窗体中加入进度条控件,然后在触发进度条的事件中将加载进度报告给 进度条控件。 注: 博客主页: 实现设计进度条窗体新建窗体FrmProgressBar,打开设计页面,打开DevExpress的工具箱。 拖拽一个SplashScreen控件
然后再拖拽一个label和MarqueeProgressBarControl控件
然后打开其代码页面,编辑其代码为 public partial class FrmProgressBar : SplashScreen { #region 单例实现 private static string _lockFlag = "FrmProgressBarLock"; private static FrmProgressBar _instance = null; /// <summary> /// 进度条窗口实例 /// </summary> public static FrmProgressBar Instance { get { lock(_lockFlag) { if (_instance == null) { _instance = new FrmProgressBar(true); } else if (_instance.IsDisposed) { _instance = null; _instance = new FrmProgressBar(true); } return _instance; } } } #endregion #region 字段定义 private bool _isShowTitle = false; #endregion #region 构造方法 private FrmProgressBar() { InitializeComponent(); } private FrmProgressBar(bool isShowTitle) { InitializeComponent(); this._isShowTitle = isShowTitle; this.marqueeProgressBarControl1.Properties.ShowTitle = this._isShowTitle; } #endregion #region 属性定义 /// <summary> /// 是否显示标题 /// </summary> public bool IsShowTitle { get { return this._isShowTitle; } set { this._isShowTitle = value; this.marqueeProgressBarControl1.Properties.ShowTitle = this._isShowTitle; } } /// <summary> /// 提示文本 /// </summary> public string NotifyText { get { return this.labelControl2.Text; } set { this.labelControl2.Text = value; } } /// <summary> /// 进度值 /// </summary> public int ProgressValue { get { return (int)this.marqueeProgressBarControl1.EditValue; } set { this.marqueeProgressBarControl1.Text = String.Format("{0}%", value); } } #endregion #region Overrides public override void ProcessCommand(Enum cmd, object arg) { base.ProcessCommand(cmd, arg); } #endregion public enum SplashScreenCommand { } }
调用进度条窗体需要新开一个线程去执行进度条所代表的任务,在触发进度条的事件中 BackgroundWorker bgWorker = new BackgroundWorker();
并且设置其是否报告进度属性为true bgWorker.WorkerReportsProgress = true;
然后绑定具体的进度条所代表的任务 bgWorker.DoWork -= backgroundWorker1_DoWork;
bgWorker.DoWork += backgroundWorker1_DoWork;
在此绑定的方法中就会执行具体的任务 然后设置任务进度改变的事件绑定 bgWorker.ProgressChanged -= bgWorker_ProgressChanged;
bgWorker.ProgressChanged += bgWorker_ProgressChanged;
在此方法中进行进度条进度与任务执行进度的绑定 private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { if (e.ProgressPercentage >= 0 && e.ProgressPercentage <= 100) { Dialog.FrmProgressBar.Instance.ProgressValue = e.ProgressPercentage; } } 然后设置任务执行完之后关闭进度条窗口 bgWorker.RunWorkerCompleted -= bgWorker_RunWorkerCompleted;
bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted;
在执行完的方法中 private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Dialog.FrmProgressBar.Instance.Dispose(); //关闭进度对话框 } 然后开始执行后台操作 bgWorker.RunWorkerAsync(); 然后最后让进度条窗体显示 Dialog.FrmProgressBar.Instance.ShowDialog(); 需要注意的是: 在DoWork 中绑定的具体的执行的任务中一定是佷费时间的任务,如果就是简单的 几个for循环,那么会看不到效果,因为这两个线程没有时间差,所以会同时显示与关闭。 所以在具体执行的后台任务中要执行有时间差的任务,比如读取大数据量文件。 并且在执行此任务时要根据执行的任务进度去进行报告。 在DoWork绑定的方法中 BackgroundWorker bgWorker = sender as BackgroundWorker; 。。。 bgWorker.ReportProgress(10); //10% 。。。 bgWorker.ReportProgress(65); 。。。 bgWorker.ReportProgress(100); 完整示例代码//创建新的后台线程 BackgroundWorker bgWorker = new BackgroundWorker(); //设置线程是否报告进度为true bgWorker.WorkerReportsProgress = true; //绑定具体的后台任务的方法,在此方法中会报告进度 bgWorker.DoWork -= backgroundWorker1_DoWork; bgWorker.DoWork += backgroundWorker1_DoWork; //当进度改变时事件绑定,将绑定的进度作为进度条的进度 bgWorker.ProgressChanged -= bgWorker_ProgressChanged; bgWorker.ProgressChanged += bgWorker_ProgressChanged; //后台线程执行完事件绑定,会关闭进度条窗口 bgWorker.RunWorkerCompleted -= bgWorker_RunWorkerCompleted; bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted; //开始执行后台操作 bgWorker.RunWorkerAsync(); //显示进度条窗口 Dialog.FrmProgressBar.Instance.ShowDialog(); 执行后台任务的方法 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker bgWorker = sender as BackgroundWorker; List<Cycle> cycles = null; List<Step> steps = null; List<Record> mainRecords = null; bgWorker.ReportProgress(10); //10% #region 加载循环数据 string cycleDataFile = String.Format("{0}{1}", Global.Instance.CurrDataFile, Global.CYCLE_EXT); if (System.IO.File.Exists(cycleDataFile)) { using (System.IO.Stream fs = new System.IO.FileStream(cycleDataFile, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { cycles = ProtoBuf.Serializer.Deserialize<List<Cycle>>(fs); } } bgWorker.ReportProgress(40); #endregion #region 加载工步数据 string stepDataFile = String.Format("{0}{1}", Global.Instance.CurrDataFile, Global.STEP_EXT); if (System.IO.File.Exists(stepDataFile)) { using (System.IO.Stream fs = new System.IO.FileStream(stepDataFile, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { steps = ProtoBuf.Serializer.Deserialize<List<Step>>(fs); } } bgWorker.ReportProgress(70); #endregion #region 加载主通道数据 string mainRecordDataFile = String.Format("{0}{1}", Global.Instance.CurrDataFile, Global.MAIN_EXT); if (System.IO.File.Exists(mainRecordDataFile)) { using (System.IO.Stream fs = new System.IO.FileStream(mainRecordDataFile, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { mainRecords = ProtoBuf.Serializer.Deserialize<List<Record>>(fs); } } #endregion bgWorker.ReportProgress(100); }
后台任务进度改变事件 private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { if (e.ProgressPercentage >= 0 && e.ProgressPercentage <= 100) { Dialog.FrmProgressBar.Instance.ProgressValue = e.ProgressPercentage; } } 后台任务执行完毕事件 private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Dialog.FrmProgressBar.Instance.Dispose(); //关闭进度对话框 }
|
|