在开发Winform程序的时候,经常会用到等待窗口(如网络通讯、数据库连接等需要一定时间来执行的操作),这样可以给用户提供更好的体验。
等待窗口的主要功能是一边执行需要等待的操作,一边显示一个等待界面。当执行完毕时等待界面消失。用户可以提前取消操作,还可以设置操作的最大等待时间,若超过指定时间仍没完成操作可结束当前操作。等待窗口的操作处理内容可用λ表达式,在后面的应用实例中可看到使用方法。
实现界面如下图:

等待界面主要包含的部分:
- 等待图片;
- 等待消息文字("正在处理数据,请稍后..."):可自定义;
- 计时器:可设置不显示;
- 取消返回按钮:可设置不显示;
- 另外等待窗口显示和关闭的时候都有渐变的一个简单特效,等待窗口的颜色是在一定范围内随即的。
等待窗口实现代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WinForm_Test
{
public partial class frmWaitingBox : Form
{
#region Properties
private int _MaxWaitTime;
private int _WaitTime;
private bool _CancelEnable;
private IAsyncResult _AsyncResult;
private EventHandler<EventArgs> _Method;
private bool _IsShown = true;
private readonly int _EffectCount = 10;
private readonly int _EffectTime = 500;
/// <summary>
/// 控制界面显示的特性
/// </summary>
private Timer _Timer;
public string Message { get; private set; }
public int TimeSpan { get; set; }
public bool FormEffectEnable { get; set; }
#endregion
#region frmWaitingBox
public frmWaitingBox(EventHandler<EventArgs> method,int maxWaitTime,string waitMessage,bool cancelEnable,bool timerVisable)
{
maxWaitTime *= 1000;
Initialize(method, maxWaitTime,waitMessage, cancelEnable, timerVisable);
}
public frmWaitingBox(EventHandler<EventArgs> method)
{
int maxWaitTime=60*1000;
string waitMessage = "正在处理数据,请稍后...";
bool cancelEnable=true;
bool timerVisable=true;
Initialize(method, maxWaitTime,waitMessage, cancelEnable, timerVisable);
}
public frmWaitingBox(EventHandler<EventArgs> method, string waitMessage)
{
int maxWaitTime = 60 * 1000;
bool cancelEnable = true;
bool timerVisable = true;
Initialize(method, maxWaitTime, waitMessage, cancelEnable, timerVisable);
}
public frmWaitingBox(EventHandler<EventArgs> method, bool cancelEnable, bool timerVisable)
{
int maxWaitTime = 60*1000;
string waitMessage = "正在处理数据,请稍后...";
Initialize(method, maxWaitTime,waitMessage, cancelEnable, timerVisable);
}
#endregion
#region Initialize
private void Initialize(EventHandler<EventArgs> method, int maxWaitTime,string waitMessage,bool cancelEnable, bool timerVisable)
{
InitializeComponent();
//initialize form
this.FormBorderStyle = FormBorderStyle.None;
this.StartPosition = FormStartPosition.CenterParent;
this.ShowInTaskbar = false;
Color[] c = GetRandColor();
this.panel1.BackColor = c[0];
this.BackColor = c[1];
this.labMessage.Text = waitMessage;
_Timer = new Timer();
_Timer.Interval = _EffectTime/_EffectCount;
_Timer.Tick += _Timer_Tick;
this.Opacity = 0;
FormEffectEnable = true;
//para
TimeSpan = 500;
Message = string.Empty;
_CancelEnable = cancelEnable;
_MaxWaitTime = maxWaitTime;
_WaitTime = 0;
_Method = method;
this.pictureBoxCancel.Visible = _CancelEnable;
this.labTimer.Visible = timerVisable;
this.timer1.Interval = TimeSpan;
this.timer1.Start();
}
#endregion
#region Color
private Color[] GetRandColor()
{
int rMax = 248;
int rMin = 204;
int gMax = 250;
int gMin = 215;
int bMax = 250;
int bMin = 240;
Random r = new Random(DateTime.Now.Millisecond);
int r1 = r.Next(rMin, rMax);
int r2 = r1 + 5;
int g1 = r.Next(gMin, gMax);
int g2 = g1 + 5;
int b1 = r.Next(bMin, bMax);
int b2 = b1 + 5;
Color c1 = Color.FromArgb(r1, g1, b1);
Color c2 = Color.FromArgb(r2, g2, b2);
Color[] c = { c1, c2 };
return c;
}
#endregion
#region Events
private void btnCancel_Click(object sender, EventArgs e)
{
this.Message = "您结束了当前操作!";
this.Close();
}
private void timer1_Tick(object sender, EventArgs e)
{
_WaitTime += TimeSpan;
this.labTimer.Text = string.Format("{0}秒", _WaitTime / 1000);
if (!this._AsyncResult.IsCompleted)
{
if (_WaitTime > _MaxWaitTime)
{
Message = string.Format("处理数据超时{0}秒,结束当前操作!", _MaxWaitTime / 1000);
this.Close();
}
}
else
{
this.Message = string.Empty;
this.Close();
}
}
private void frmWaitingBox_Shown(object sender, EventArgs e)
{
_AsyncResult = _Method.BeginInvoke(null, null, null, null);
//Effect
if (FormEffectEnable)
{
_Timer.Start();
}
else
this.Opacity = 1;
}
private void frmWaitingBox_FormClosing(object sender, FormClosingEventArgs e)
{
if (FormEffectEnable)
{
if(this.Opacity>=1)
e.Cancel = true;
_Timer.Start();
}
}
private void _Timer_Tick(object sender, EventArgs e)
{
if (_IsShown)
{
if (this.Opacity >= 1)
{
_Timer.Stop();
_IsShown = false;
}
this.Opacity += 1.00 / _EffectCount;
}
else
{
if (this.Opacity <= 0)
{
_Timer.Stop();
_IsShown = true;
this.Close();
}
this.Opacity -= 1.00 / _EffectCount;
}
}
#endregion
}
}
应用实例代码:
string res;
DataTable dt=null;
frmWaitingBox f = new frmWaitingBox((obj,args)=>
{
Thread.Sleep(5000);
string sql = "SELECT * FROM [test].[dbo].[studentInfo]";
SQLHelper sqlHelper=new SQLHelper();
dt = sqlHelper.ExecuteSqlStr(sql,out res);
});
f.ShowDialog(this);
dataGridView1.DataSource = dt;
源码下载:下载地址——(https://files.cnblogs.com/anding/WinForm_Test1.rar)