引言
当我们的软件加载资源比较多,需要耗费一定时间的时候,我们希望软件可以有一个类似于欢迎的加载界面,这样可以简单地显示当前的加载进度,使得用户体验更加友好。
开发准备
- 首先创建一个Windows窗体应用项目,项目名称为thinger.com.SplashProject,并创建一个窗体,取名FrmMain,绘制一个简单的UI界面,用于表示主界面。
- 创建一个Splasher类,包含创建窗体实例、显示动态窗体、显示窗体状态和关闭动画窗体。
- 创建Splasher类
public class Splasher
{
private delegate void SplashStatusChangedHandle(string NewStatusInfo);
private static Form m_SplashForm = null;
private static ISplashForm m_SplashInterface = null;
private static Thread m_SplashThread = null;
private static string m_TempStatus = string.Empty;
} - 显示动画窗体
public static void Show(Type splashFormType)
{
if (m_SplashThread != null)
return;
if (splashFormType == null)
return;
m_SplashThread = new Thread(new ThreadStart(delegate()
{
CreateInstance(splashFormType);
Application.Run(m_SplashForm);
}));
m_SplashThread.IsBackground = true;
m_SplashThread.SetApartmentState(ApartmentState.STA);
m_SplashThread.Start();
} - 创建窗体实例
private static void CreateInstance(Type FormType)
{
object obj = FormType.InvokeMember(null,
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.CreateInstance, null, null, null);
m_SplashForm = obj as Form;
m_SplashInterface = obj as ISplashForm;
if (m_SplashForm == null)
{
throw (new Exception("动画窗体必须为Form窗体"));
}
if (m_SplashInterface == null)
{
throw (new Exception("动画窗体必须继承ISplashForm"));
}
if (!string.IsNullOrEmpty(m_TempStatus))
m_SplashInterface.SetStatusInfo(m_TempStatus);
} - 显示窗体状态
public static string Status
{
set
{
if (m_SplashInterface == null || m_SplashForm == null)
{
m_TempStatus = value;
return;
}
m_SplashForm.Invoke(
new SplashStatusChangedHandle(delegate(string str) { m_SplashInterface.SetStatusInfo(str); }),
new object[] { value }
);
}
} - 关闭动画窗体
public static void Close()
{
if (m_SplashThread == null || m_SplashForm == null) return;
try
{
m_SplashForm.Invoke(new MethodInvoker(m_SplashForm.Close));
}
catch (Exception)
{
}
m_SplashThread = null;
m_SplashForm = null;
}
public interface ISplashForm
{
void SetStatusInfo(string NewStatusInfo);
}创建一个新窗体,取名为FrmSplash,添加一个状态Label标签,该窗体继承ISplashForm,并实现SetStatusInfo方法,代码如下:
void ISplashForm.SetStatusInfo(string NewStatusInfo)
{
lbStatusInfo.Text = NewStatusInfo;
}FrmSplash窗体做以下设置:
将FormBorderStyle属性设成None,即没有窗体边框 将StartPosition属性设成CenterScreen,即总是居中 将TopMost属性设成True,即总是在顶部 将UseWaitCursor属性设成Ture,即显示等待光标 增加一个PictureBox控件,Dock设置为Fill,选择一个好看的背景图片
UI界面设计如下所示:
功能实现
- 在Program程序入口处,加入一行代码Splasher.Show(typeof(FrmSplash)),用于显示SplashForm
static class Program
{/// <summary>/// 应用程序的主入口点。/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Splasher.Show(typeof(FrmSplash));
Application.Run(new FrmMain());
}
} - 在FrmMain窗体的加载事件中,编写代码如下,这里使用Thread.Sleep来模拟处理相关信息
private void FrmMain_Load(object sender, EventArgs e)
{//模拟初始化相关信息
Thread.Sleep(500);
Splasher.Status = "正在加载系统模块......";
Thread.Sleep(1000);
Splasher.Status = "正在加载控件信息......";
Thread.Sleep(1000);
Splasher.Status = "正在加载配置文件......";
Thread.Sleep(1000);
Splasher.Status = "正在连接PLC设备......";
this.Opacity = 0;
this.Shown += FrmMain_Shown;
} - 在FrmMain显示完成事件中,关闭SplashForm,代码如下所示:
private void FrmMain_Shown(object sender, EventArgs e)
{
this.Opacity = 100;
Splasher.Status = "初始化完毕......";
Splasher.Close();
} - 最终运行效果如下所示: