相信很多工作之后经常需要做进度条,尤其是客户端程序上传文件或者执行某些任务的时候,有进度条会让界面友好很多。最近也是蛋疼到不行,新接手的项目里一会要执行单个任务的,一会要执行多个任务的,所以进度条的个数也不确定,还要组长还跑来跟我要进度条窗口,索性自己动手画一个可复用的进度条窗口,废话少说,先上图
单进度条模式
双进度条模式
窗口是纯手绘的,只需要设置一个参数就能显示对应个数的进度条,这样能满足多数情况的使用。
下面是简单的代码实现
namespace HApplication { public delegate void Func(); public delegate void SetKeyValDelegate<T1, T2>(T1 key, T2 val); public delegate void ExcuteDelegate(TransferDlg dlg, params object[] args); public class TransferDlg : Form { #region << 变量 >> private static TransferDlg _cur = null; private Thread _thread = null; #endregion private void OnCancelClick(object sender, EventArgs e) { if (_thread.ThreadState != ThreadState.Stopped) { _thread.Abort(); } this.Close(); } private void OnMouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { ReleaseCapture(); SendMessage(this.Handle, WM_NCLBUTTONDOWN, (IntPtr)HTCAPTION, IntPtr.Zero); } } public new void Close() { if (this.InvokeRequired) { this.Invoke(new Func(Close)); return; } base.Close(); } #region << 接口 >> /// <summary> /// 启用阻塞式对话框显示进度条 /// </summary> /// <param name="num">指示该对话框中进度条的个数</param> /// <param name="func">期间需要执行的函数</param> /// <param name="args">为执行函数提供参数</param> public static void Start(int num, ExcuteDelegate func, params object[] args) { _cur = new TransferDlg(num); _cur._thread = new Thread(new ThreadStart(delegate() { func(_cur, args); _cur.Close(); })); _cur._thread.Name = "Work Thread"; _cur._thread.Start(); _cur.ShowDialog(); } } }
调用的时候也非常容易
class App { [STAThread] static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); TransferDlg.Start(1, Run1, 100000, 100); TransferDlg.Start(2, Run2, 1000, 100); } public static void Run1(TransferDlg dlg, params object[] args) { int arg0 = (int)args[0]; dlg.SetMaxValue(0, arg0); for (int i = 0; i < arg0; i++) { dlg.SetCurValue(0, i); dlg.SetText(0, string.Format("正在上传文件 {0} / {1}", i, arg0)); } } public static void Run2(TransferDlg dlg, params object[] args) { int arg0 = (int)args[0]; int arg1 = (int)args[1]; dlg.SetMaxValue(0, arg0); for (int i = 0; i < arg0; i++) { dlg.SetCurValue(0, i); dlg.SetText(0, string.Format("正在上传文件 {0} / {1}", i, arg0)); dlg.SetMaxValue(1, arg1); for (int j = 0; j < arg1; j++) { dlg.SetCurValue(1, j); dlg.SetText(1, string.Format("文件上传进度 {0} / {1}", j, arg1)); } } } }
写好需要执行任务的函数,参数为上文中的
void ExcuteDelegate(TransferDlg dlg, params object[] args)调用TransferDlg的静态方法 Start,第一个参数为要显示进度条的个数,第二参数为你写的要执行任务的函数,第三个参数是变参,可不传,这些变参将传给你要执行的函数。
在函数内部可以直接dlg中的值,已写线程安全,TransferDlg提供四个公开函数,分别用于设置 标题,文本,进度条最大,进度条当前值。
调用方法如:
dlg.SetTitle("标题"); dlg.SetText(0, string.Format("正在上传文件 {0} / {1}", i, arg0)); dlg.SetMaxValue(0, 100); dlg.SetCurValue(0, 10);
源码已上传至CSDN,感觉有用或者有兴趣的可以去看看,俾人一向不喜欢收积分。窗口样子要是不喜欢可以自己改。
下载地址 源代码
下如果觉得实用或者感兴趣,记得来点个赞。要知道我这可是无偿熬夜