相信很多工作之后经常需要做进度条,尤其是客户端程序上传文件或者执行某些任务的时候,有进度条会让界面友好很多。最近也是蛋疼到不行,新接手的项目里一会要执行单个任务的,一会要执行多个任务的,所以进度条的个数也不确定,还要组长还跑来跟我要进度条窗口,索性自己动手画一个可复用的进度条窗口,废话少说,先上图
单进度条模式
双进度条模式
窗口是纯手绘的,只需要设置一个参数就能显示对应个数的进度条,这样能满足多数情况的使用。
下面是简单的代码实现
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,感觉有用或者有兴趣的可以去看看,俾人一向不喜欢收积分。窗口样子要是不喜欢可以自己改。
下载地址 源代码
下如果觉得实用或者感兴趣,记得来点个赞。要知道我这可是无偿熬夜