winform进度条的实现

1.第一种方法:直接实现

(1)界面

(2)设计一个按钮事件

        private void button1_Click(object sender, EventArgs e)
        {
            progressBar1.Value = 0;  //清空进度条
            for (int i = 0; i < 100; i++)
            {
                progressBar1.Value += 1;
                textBox1.AppendText("当前进度:%" + i.ToString() + "\r\n");
                Thread.Sleep(50); 
            }
           
        }

结果为:

2.第二种方法:子窗体实现

(1)先定义一个进度条窗体progressForm.cs,添加函数

        public void AddProgress()
        {
            progressBar1.Value++;
            label1.Text = progressBar1.Value.ToString() + "%";
            label1.Refresh();

(2)主窗体添加一个按钮事件

private void button1_Click(object sender, EventArgs e)
        {
            progressForm progress = new progressForm();
            progress.Show();
            for (int i = 0; i < 100; i++)
            {
                progress.AddProgress();
                Thread.Sleep(50);  // 毫秒ms
            }
            progress.Close();
           
        }

结果如下:

 

(3)第三种方法:线程实现

效果如下:

步骤如下:

首先定义一个代理用于更新ProgressBar的值(Value)及在执行方法的时候,返回方法的处理信息。

        private delegate void SetPos(int ipos,string vinfo);//代理

相关实现函数如下

       private void button1_Click(object sender, EventArgs e)
        {
            Thread fThread = new Thread(new ThreadStart(SleepT));
            fThread.Start();
        }
        
        //定义新的线程执行函数
        private void SleepT()
        {
            for (int i = 0; i < 500; i++)   //滚动条最大值为500
            {
                System.Threading.Thread.Sleep(10);
                SetTextMsg(100 * i / 500, i.ToString() + "\r\n");
            }
        }

        //进度条值更新函数(参数必须跟声明的代理参数一样)
        private void SetTextMsg(int ipos, string vinfo)
        {
            if (this.InvokeRequired)   //InvokeRequired属性为真时,说明一个创建它以以外的线程(即SleepT)想访问它
            {
                SetPos setpos = new SetPos(SetTextMsg);
                this.Invoke(setpos, new object[] { ipos, vinfo });//SleepT线程调用本控件Form1中的方法
            }
            else
            {
                this.label1.Text = ipos.ToString() + "/100";
                this.progressBar1.Value = Convert.ToInt32(ipos);
                this.textBox1.AppendText(vinfo);
            }
        }

以上三种情况都会产生程序假死,即在进度条运行时不能点击。

4.第四种方法:BackgroundWorker控件实现,不会假死

BackgroundWorker可在单独的线程上执行操作

步骤如下:

(1)主窗体设计,为主窗体添加一个BackgroundWorker控件和按钮控件

(2)主窗体后台代码Form1.cs

namespace progress_backgroundworker
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.backgroundWorker1.WorkerReportsProgress = true;  //设置能报告进度更新
            this.backgroundWorker1.WorkerSupportsCancellation = true;  //设置支持异步取消
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.backgroundWorker1.RunWorkerAsync();  //运行backgroundWorker组件
            ProgressForm form = new ProgressForm(this.backgroundWorker1);  //显示进度条窗体
            form.ShowDialog(this);
            form.Close();
        }

        //在另一个线程上开始运行(处理进度条)
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = 0; i < 100; i++)
            {
                System.Threading.Thread.Sleep(100);
                worker.ReportProgress(i);
                if (worker.CancellationPending) //获取程序是否已请求取消后台操作
                {
                    e.Cancel = true;
                    break;
                }
            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
                MessageBox.Show("取消");
            }
            else
            {
                MessageBox.Show("完成");
            }
        }



    }
}

(3)子窗体设计

(4)子窗体代码实现ProgressForm.cs

namespace progress_backgroundworker
{
    public partial class ProgressForm : Form
    {
        private BackgroundWorker backgroundWorker1; //ProgressForm窗体事件(进度条窗体)

        public ProgressForm(BackgroundWorker bgWork)
        {
            InitializeComponent();
            // add my code
            this.backgroundWorker1 = bgWork;
            //绑定进度条改变事件
            this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            //绑定后台操作完成,取消,异常时的事件
            this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
        }


        void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.progressBar1.Value = e.ProgressPercentage;  //获取异步任务的进度百分比
        }

        void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //this.Close();  //执行完之后,直接关闭页面
        }

        //取消
        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.backgroundWorker1.CancelAsync(); //请求取消挂起的后台操作
            this.btnCancel.Enabled = false;
            this.Close();
        }
    }
}

效果如下

更多内容见参考资料

https://blog.csdn.net/ym296900664/article/details/52192289

https://www.cnblogs.com/xwzLoveCshap/p/9271592.html

圆形进度条实现

https://jingyan.baidu.com/article/eae0782742aa9d1fec54852f.html

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值