Winform下制作Splash啟動畫面
引言
當(dāng)我們的軟件加載資源比較多,需要耗費(fèi)一定時間的時候,我們希望軟件可以有一個類似于歡迎的加載界面,這樣可以簡單地顯示當(dāng)前的加載進(jìn)度,使得用戶體驗更加友好。
開發(fā)準(zhǔn)備
首先創(chuàng)建一個Windows窗體應(yīng)用項目,項目名稱為thinger.com.SplashProject,并創(chuàng)建一個窗體,取名FrmMain,繪制一個簡單的UI界面,用于表示主界面。

創(chuàng)建一個Splasher類,包含創(chuàng)建窗體實(shí)例、顯示動態(tài)窗體、顯示窗體狀態(tài)和關(guān)閉動畫窗體。
創(chuàng)建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();
}創(chuàng)建窗體實(shí)例
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);
}顯示窗體狀態(tài)
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 }
);
}
}關(guān)閉動畫窗體
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;
}
創(chuàng)建一個ISplashForm接口,如下所示:
public interface ISplashForm
{
void SetStatusInfo(string NewStatusInfo);
}創(chuàng)建一個新窗體,取名為FrmSplash,添加一個狀態(tài)Label標(biāo)簽,該窗體繼承ISplashForm,并實(shí)現(xiàn)SetStatusInfo方法,代碼如下:
void ISplashForm.SetStatusInfo(string NewStatusInfo)
{
lbStatusInfo.Text = NewStatusInfo;
}FrmSplash窗體做以下設(shè)置:
將FormBorderStyle屬性設(shè)成None,即沒有窗體邊框 將StartPosition屬性設(shè)成CenterScreen,即總是居中 將TopMost屬性設(shè)成True,即總是在頂部 將UseWaitCursor屬性設(shè)成Ture,即顯示等待光標(biāo) 增加一個PictureBox控件,Dock設(shè)置為Fill,選擇一個好看的背景圖片
UI界面設(shè)計如下所示:

在Program程序入口處,加入一行代碼Splasher.Show(typeof(FrmSplash)),用于顯示SplashForm
static class Program
{
///<summary>
/// 應(yīng)用程序的主入口點(diǎn)。
///</summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Splasher.Show(typeof(FrmSplash));
Application.Run(new FrmMain());
}
}在FrmMain窗體的加載事件中,編寫代碼如下,這里使用Thread.Sleep來模擬處理相關(guān)信息
private void FrmMain_Load(object sender, EventArgs e)
{
//模擬初始化相關(guān)信息
Thread.Sleep(500);
Splasher.Status = "正在加載系統(tǒng)模塊......";
Thread.Sleep(1000);
Splasher.Status = "正在加載控件信息......";
Thread.Sleep(1000);
Splasher.Status = "正在加載配置文件......";
Thread.Sleep(1000);
Splasher.Status = "正在連接PLC設(shè)備......";
this.Opacity = 0;
this.Shown += FrmMain_Shown;
}在FrmMain顯示完成事件中,關(guān)閉SplashForm,代碼如下所示:
private void FrmMain_Shown(object sender, EventArgs e)
{
this.Opacity = 100;
Splasher.Status = "初始化完畢......";
Splasher.Close();
}最終運(yùn)行效果如下所示:
功能實(shí)現(xiàn)
