C# ProgressBar的简单使用
ProgressBar控件(进度条)用于在win窗体中显示进度,由于它的值会不断更新,为了不让界面假死,一般都是采用多线程的方式对进度条进行管理。有关ProgressBar的理论基础跟详细知识我在这里不多说,官方文档上面都可以查阅参考。这篇随笔我就是简单演示一下对ProgressBar控件的简单使用。
先展示一下窗口界面:
左上角是两个ProgressBar,右上角按钮负责控制ProgressBar进度的开启。右下角的四个按钮看起来很熟悉是吧,因为这是在上一篇博文中所演示的Demo的基础上继续往后做的。
一、首先定义一个控制ProgressBar进度的委托方法,为什么要用委托呢?因为ProgressBar控件是由主线程创建的,而对ProgressBar的操作是放在一个子线程中的,这在后面的跨线程操作控件中需要用到委托方法。代码如下:
1 private delegate void DelSetPro(int pro, ProgressBar proBar);//设置进度条进度的委托方法
二、定义一个共通的方法,用于设置进度条的进度,代码如下:
1 ///设置ProgressBar进度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 else 17 { 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 else 13 { 14 pro.Visible = false; 15 } 16 }
五、接下就是对第一个进度条的具体操作了,在这个方法里会用到上面已经定义好的两个方法。请注意:ProgressBar的Maximum的默认值为100,Minimum的默认值为0,起初没注意Maximum,导致了超值异常。代码如下:
1 ///操作ProgressBar01控件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 ///Form1.cs14 /// 设置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 }
以上!