啟動畫面能提升應用程式感知效能,掩蓋初始化延遲。本文介紹標準實作模式:主視窗載入時以對話框模式顯示啟動畫面,配合 Timer 或背景工作執行初始化,完成後自動關閉。
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
// 以對話框模式顯示啟動畫面(阻塞主視窗顯示)
using (var splash = new SplashForm())
{
splash.ShowDialog(this); // 設定 Owner 確保置中顯示
}
// 啟動畫面關閉後,繼續主視窗初始化或直接進入應用
InitializeMainForm();
}
private void InitializeMainForm()
{
// 載入設定、連接資料庫、初始化模組等耗時操作
// 建議改為非同步初始化,避免凍結 UI
}
}
public partial class SplashForm : Form
{
private readonly System.Windows.Forms.Timer _timer;
private int _progress = 0;
public SplashForm()
{
InitializeComponent();
ConfigureForm();
InitializeTimer();
}
private void ConfigureForm()
{
// 關鍵:無邊框、無標題列、置中顯示
this.FormBorderStyle = FormBorderStyle.None;
this.StartPosition = FormStartPosition.CenterParent; // 相對 Owner 置中
this.ShowInTaskbar = false;
this.TopMost = true; // 確保顯示在最上層
// 設定背景圖片
this.BackgroundImage = Properties.Resources.SplashScreen; // 從資源載入
this.BackgroundImageLayout = ImageLayout.Stretch;
this.ClientSize = this.BackgroundImage.Size;
}
private void InitializeTimer()
{
_timer = new System.Windows.Forms.Timer { Interval = 100 };
_timer.Tick += Timer_Tick;
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
_timer.Start();
// 或在背景執行緒執行初始化工作
Task.Run(PerformInitialization);
}
private async void PerformInitialization()
{
try
{
// 模擬初始化步驟
await InitializeDatabaseAsync();
ReportProgress(30, "資料庫連線完成");
await LoadConfigurationAsync();
ReportProgress(60, "設定載入完成");
await InitializeModulesAsync();
ReportProgress(90, "模組初始化完成");
await FinalizeStartupAsync();
ReportProgress(100, "啟動完成");
}
catch (Exception ex)
{
// 記錄錯誤,決定是否繼續或中止
ReportProgress(100, $"初始化失敗:{ex.Message}");
}
}
private void ReportProgress(int percent, string message)
{
if (this.InvokeRequired)
{
this.Invoke(() => ReportProgress(percent, message));
return;
}
_progress = percent;
lblStatus.Text = message;
progressBar.Value = percent;
if (percent >= 100)
{
_timer.Stop();
// 短暫延遲讓使用者看完 100%
await Task.Delay(500);
this.Close();
}
}
private void Timer_Tick(object sender, EventArgs e)
{
// 動畫效果:閃爍標誌、旋轉圖示等
lblLoading.Visible = !lblLoading.Visible;
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
_timer?.Stop();
_timer?.Dispose();
base.OnFormClosed(e);
}
// 模擬初始化方法
private Task InitializeDatabaseAsync() => Task.Delay(800);
private Task LoadConfigurationAsync() => Task.Delay(600);
private Task InitializeModulesAsync() => Task.Delay(1000);
private Task FinalizeStartupAsync() => Task.Delay(300);
}
避免阻塞主執行緒,使用 `Show` 而非 `ShowDialog`,配合 `Task` 協調:
public partial class MainForm : Form
{
private SplashForm _splash;
public MainForm()
{
InitializeComponent();
this.Load += MainForm_Load;
this.Shown += MainForm_Shown;
}
private async void MainForm_Load(object sender, EventArgs e)
{
_splash = new SplashForm();
_splash.Show(this); // 非阻塞顯示
// 並行執行:UI 動畫 + 後端初始化
await Task.WhenAll(
_splash.RunAnimationAsync(),
InitializeApplicationAsync()
);
_splash.Close();
_splash.Dispose();
}
private async Task InitializeApplicationAsync()
{
// 真實初始化工作
await Task.Delay(2000);
}
}
public partial class SplashForm : Form
{
public async Task RunAnimationAsync()
{
while (this.Visible && !this.IsDisposed)
{
// 更新動畫
await Task.Delay(100);
}
}
}
啟動畫面是使用者體驗的第一印象,投入適度精力實作專業的啟動體驗,能顯著提升應用程式的感知品質。