欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Winform中封装DevExpress的MarqueeProgressBarComtrol实现弹窗式进度条效果

程序员文章站 2022-04-02 18:29:27
场景 在Winform中实现弹窗式进度条 就是新建一个窗体,然后在窗体中加入进度条控件,然后在触发进度条的事件中将加载进度报告给 进度条控件。 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书、教程推送 ......

场景

在winform中实现弹窗式进度条

Winform中封装DevExpress的MarqueeProgressBarComtrol实现弹窗式进度条效果

 

 

Winform中封装DevExpress的MarqueeProgressBarComtrol实现弹窗式进度条效果

就是新建一个窗体,然后在窗体中加入进度条控件,然后在触发进度条的事件中将加载进度报告给

进度条控件。

注:

博客主页:

关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

设计进度条窗体

新建窗体frmprogressbar,打开设计页面,打开devexpress的工具箱。

拖拽一个splashscreen控件

Winform中封装DevExpress的MarqueeProgressBarComtrol实现弹窗式进度条效果

 

 

然后再拖拽一个label和marqueeprogressbarcontrol控件

Winform中封装DevExpress的MarqueeProgressBarComtrol实现弹窗式进度条效果

 

 

然后打开其代码页面,编辑其代码为

 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();           //关闭进度对话框
        }