Winform中封装DevExpress的MarqueeProgressBarComtrol实现弹窗式进度条效果
程序员文章站
2022-04-02 18:29:27
场景 在Winform中实现弹窗式进度条 就是新建一个窗体,然后在窗体中加入进度条控件,然后在触发进度条的事件中将加载进度报告给 进度条控件。 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书、教程推送 ......
场景
在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(); //关闭进度对话框 }
上一篇: 对RESTful Api的简单记录
下一篇: 牛客OJ:把正方形矩阵按顺时针输出