iT邦幫忙

1

Windows Form 加入載入動畫


在 Windows Forms 應用程式中加入「載入動畫」並不簡單:解決「UI 執行緒阻塞」問題。
以下是說明、實作步驟及範例程式碼。

什麼是「UI 執行緒阻塞」?

當一個表單(Form)取得操作焦點時,其他在背景運行的表單將暫停動作。
因此,當載入動畫出現時,必須另開執行緒在背景中執行接著要顯示的新表單,才能讓動畫持續播放。

主執行緒的控制權問題

這時又產生了一個問題...
由於新表單是透過另一個執行緒開啟的,當新表單顯示時,該執行緒會取得控制權成為主執行緒,
而負責動畫的執行緒則失去控制權,使得關閉動畫的操作無法順利執行。
因此,必須將「關閉動畫」的指令交由處理新表單的執行緒來執行。

完整實作流程

  1. 以對話框的形式顯示載入動畫表單,鎖住其他表單並強制使用者等待。
  2. 在背景執行緒中初始化新表單,然後關閉動畫並顯示新表單。
  3. 等待背景執行緒完成操作。

藉由使用 async / await 關鍵字,能用最少的程式碼完成以上流程。

範例程式 Sample Code

表單及元件配置:

  1. 建立 3 張 Windows Form:Form1、Form2及FormLoading。
  2. 在 FormLoading 表單中加入一個 PictureBox 元件,放入 loading.gif 作為載入動畫(GIF 來源:GIFER 網站:https://gifer.com/en/ZKZg
  3. 在 Form1 放置 1 個 button,name 屬性為「btnOpenForm2」, 顯示文字是「Open Form2」。
  4. Form2 放置 1 個 Lable 元件顯示文字「load complete」,並在 Form2 初始化時等待 5 秒模擬載入延遲。
  5. 在 btnOpenForm2 的 Click 事件中,加入程式碼以背景執行緒開啟新表單,並控制動畫的關閉與新表單的顯示。

Form1.cs

private async void btnOpenForm2_Click(object sender, EventArgs e)
{
    using (var formLoading = new FormLoading())
    {
        // 在背景執行緒初始化 Form2,完成後關閉動畫再顯示 Form2
        var loadForm2Task = Task.Run(() =>
        {
            var form2 = new Form2();
            formLoading.DialogResult = DialogResult.OK;
            form2.ShowDialog();
        });

        // 以Dialog顯示loading form,鎖住其他的表單強迫使用者等待
        formLoading.ShowDialog();

        // 等待 Form2 完成初始化並顯示
        await loadForm2Task;
    }
}

Form2.cs

public Form2()
{
    InitializeComponent();
    LoadData();
}

private void LoadData()
{
    // 模擬載入時間 (非同步等待 5 秒)
    Thread.Sleep(5000);

    Label lbl = new Label { Text = "loading complete", AutoSize = true };
    this.Controls.Add(lbl);
}

FormLoading.cs

public FormLoading()
{
    InitializeComponent();
    this.StartPosition = FormStartPosition.CenterParent;
    this.FormBorderStyle = FormBorderStyle.None;
}

本文同步發表至我的Blog


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言