ProgressBar控件(进度条)用于在win窗体中显示进度,由于它的值会不断更新,为了不让界面假死,一般都是采用多线程的方式对进度条进行管理。有关ProgressBar的理论基础跟详细知识我在这里不多说,都可以查阅参考。这篇随笔我就是简单演示一下对ProgressBar控件的简单使用。
先展示一下窗口界面:
左上角是两个ProgressBar,右上角按钮负责控制ProgressBar进度的开启。右下角的四个按钮看起来很熟悉是吧,因为这是在的基础上继续往后做的。
一、首先定义一个控制ProgressBar进度的委托方法,为什么要用委托呢?因为ProgressBar控件是由主线程创建的,而对ProgressBar的操作是放在一个子线程中的,这在后面的跨线程操作控件中需要用到委托方法。代码如下:
1 private delegate void DelSetPro(int pro, ProgressBar proBar);//设置进度条进度的委托方法
二、定义一个共通的方法,用于设置进度条的进度,代码如下:
1 ///2 /// 设置ProgressBar的进度。 3 /// 4 /// 5 /// 6 private void SetProgressMessage(int pro, ProgressBar proBar) 7 { 8 //如果当前调用方不是创建控件的一方,则需要使用this.Invoke() 9 //在这里,ProgressBar控件是由主线程创建的,所以子线程要对该控件进行操作10 //必须执行this.InvokeRequired进行判断。11 if (this.InvokeRequired)12 {13 DelSetPro setPro = new DelSetPro(SetProgressMessage);14 this.Invoke(setPro, new object[] { pro, proBar });15 }16 else17 {18 proBar.Value = Convert.ToInt32(pro);19 }20 }
三、我希望ProgressBar的进度完成后,可以弹出一个确认窗口让我知道,并且确认后消失。这个跟设置ProgressBar的进度大同小异,只是具体的实现细节不一样。委托方法代码如下:
1 private delegate void DelSetProVisi(ProgressBar proBar);//设置进度条消失的委托方法
四、定义一个共通的方法,用于让进度条消失,代码如下:
1 ///2 /// 让控件ProgressBar消失。 3 /// 4 /// 5 private void SetProgressBarVisi(ProgressBar pro) 6 { 7 if (this.InvokeRequired) 8 { 9 DelSetProVisi setProVisi = new DelSetProVisi(SetProgressBarVisi);10 this.Invoke(setProVisi, new object[] { pro });11 }12 else13 {14 pro.Visible = false;15 }16 }
五、接下就是对第一个进度条的具体操作了,在这个方法里会用到上面已经定义好的两个方法。请注意:ProgressBar的Maximum的默认值为100,Minimum的默认值为0,起初没注意Maximum,导致了超值异常。代码如下:
1 ///2 /// 操作ProgressBar01 3 /// 4 private void SleepForProgressBar01() 5 { 6 for (int i = 1; i <= 100; i++) 7 { 8 Thread.Sleep(100); 9 SetProgressMessage(i, progressBar1);10 }11 DialogResult dr01 = MessageBox.Show("ProgressBar01 has been finished!");12 if (dr01.Equals(DialogResult.OK))13 {14 SetProgressBarVisi(progressBar1);15 }16 }
六、对第二个ProgressBar02控件的具体操作跟上面差不多,只是具体的进度不一样。就不赘述了。下面就直接展示一下实现效果图:
七、上面的几个步骤我拆解得比较细一点,可能初看起来有点乱,还有具体的一些细节方面我暂时也没有考虑太多,目前只是单纯的简单上手,在代码的优化方面应该还可以做得更好一点。这个Demo比较简单的,下面我就贴上Form1.cs的所有代码,欢迎各位批评指正。代码如下:
1 using System; 2 using System.Threading; 3 using System.Windows.Forms; 4 using WinFormsAppGame.Properties; 5 6 namespace WinFormsAppGame 7 { 8 public partial class Form1 : Form 9 { 10 private delegate void DelSetPro(int pro, ProgressBar proBar);//设置进度条进度的委托方法 11 private delegate void DelSetProVisi(ProgressBar proBar);//设置进度条消失的委托方法 12 13 ///14 /// 设置ProgressBar的进度。 15 /// 16 /// 17 /// 18 private void SetProgressMessage(int pro, ProgressBar proBar) 19 { 20 //如果当前调用方不是创建控件的一方,则需要使用this.Invoke() 21 //在这里,ProgressBar控件是由主线程创建的,所以子线程要对该控件进行操作 22 //必须执行this.InvokeRequired进行判断。 23 if (this.InvokeRequired) 24 { 25 DelSetPro setPro = new DelSetPro(SetProgressMessage); 26 this.Invoke(setPro, new object[] { pro, proBar }); 27 } 28 else 29 { 30 proBar.Value = Convert.ToInt32(pro); 31 } 32 } 33 34 ///35 /// 让控件ProgressBar消失。 36 /// 37 /// 38 private void SetProgressBarVisi(ProgressBar pro) 39 { 40 if (this.InvokeRequired) 41 { 42 DelSetProVisi setProVisi = new DelSetProVisi(SetProgressBarVisi); 43 this.Invoke(setProVisi, new object[] { pro }); 44 } 45 else 46 { 47 pro.Visible = false; 48 } 49 } 50 51 ///52 /// 操作ProgressBar01 53 /// 54 private void SleepForProgressBar01() 55 { 56 for (int i = 1; i <= 100; i++) 57 { 58 Thread.Sleep(10); 59 SetProgressMessage(i, progressBar1); 60 } 61 DialogResult dr01 = MessageBox.Show("ProgressBar01 has been finished!"); 62 if (dr01.Equals(DialogResult.OK)) 63 { 64 SetProgressBarVisi(progressBar1); 65 } 66 } 67 68 ///69 /// 操作ProgressBar02 70 /// 71 private void SleepForProgressBar02() 72 { 73 for (int j = 1; j <= 100; j++) 74 { 75 Thread.Sleep(30); 76 SetProgressMessage(j, progressBar2); 77 } 78 DialogResult dr02 = MessageBox.Show("ProgressBar02 has been finished!"); 79 if (dr02.Equals(DialogResult.OK)) 80 { 81 SetProgressBarVisi(progressBar2); 82 } 83 } 84 85 ///86 /// 监听方向键的KeyDown事件 87 /// 88 /// 89 /// 90 private void Form1_KeyDown(object sender, KeyEventArgs e) 91 { 92 switch (e.KeyCode) 93 { 94 case Keys.Left: 95 buttonLeft.BackgroundImage = Resources.left; 96 break; 97 case Keys.Up: 98 buttonUP.BackgroundImage = Resources.up; 99 break;100 case Keys.Right:101 buttonRight.BackgroundImage = Resources.right;102 break;103 case Keys.Down:104 buttonDown.BackgroundImage = Resources.down;105 break;106 }107 }108 109 ///110 /// 监听方向键的KeyUp事件111 /// 112 /// 113 /// 114 private void Form1_KeyUp(object sender, KeyEventArgs e)115 {116 switch (e.KeyCode)117 {118 case Keys.Left:119 buttonLeft.BackgroundImage = Resources.left_dark;120 break;121 case Keys.Up:122 buttonUP.BackgroundImage = Resources.up_dark;123 break;124 case Keys.Right:125 buttonRight.BackgroundImage = Resources.right_dark;126 break;127 case Keys.Down:128 buttonDown.BackgroundImage = Resources.down_dark;129 break;130 }131 }132 133 ///134 /// 重写ProcessDialogKey,来允许监听方向键135 /// 136 /// 137 ///138 protected override bool ProcessDialogKey(Keys keycode)139 {140 switch (keycode)141 {142 case Keys.Left:143 case Keys.Up:144 case Keys.Right:145 case Keys.Down:146 return false;147 }148 return true;149 }150 151 public Form1()152 {153 InitializeComponent();154 this.KeyPreview = true;//让界面能够捕捉到键盘事件155 //this.Cursor.Dispose();//在主界面中禁用鼠标156 }157 158 private void button1_Click(object sender, EventArgs e)159 {160 Thread pro01Thread = new Thread(new ThreadStart(SleepForProgressBar01));161 Thread pro02Thread = new Thread(new ThreadStart(SleepForProgressBar02));162 pro01Thread.Start();163 pro02Thread.Start();164 }165 }166 }
以上!