在 C# 開發中,若需於執行耗時操作時顯示進度,常見做法是利用子執行緒更新進度條。若希望以模態視窗呈現進度條,則可在子執行緒邏輯上稍作調整即可實現。
首先建立一個專門的進度條表單(Form),在其上放置 ProgressBar 控制項,並將 ControlBox 屬性設為 false 以隱藏標題列按鈕。接著新增一個公用方法 Increase(int nValue),用於控制進度條遞增量,並根據進度是否達到上限決定是否關閉視窗。
/// <summary>
/// 增加進度條數值
/// </summary>
/// <param name="nValue">遞增量</param>
/// <returns>是否繼續遞增</returns>
public bool Increase(int nValue)
{
if (nValue > 0)
{
if (prcBar.Value + nValue < prcBar.Maximum)
{
prcBar.Value += nValue;
return true;
}
else
{
prcBar.Value = prcBar.Maximum;
this.Close();
return false;
}
}
return false;
}
在主表單中定義兩個私有欄位:一個保存進度條視窗實例,另一個為委托型別,指向進度條視窗的 Increase 方法。
private frmProcessBar myProcessBar = null;
private delegate bool IncreaseHandle(int nValue);
private IncreaseHandle myIncrease = null;
提供開啟進度條視窗的方法,使用 ShowDialog() 以模態方式顯示:
private void ShowProcessBar()
{
myProcessBar = new frmProcessBar();
myIncrease = new IncreaseHandle(myProcessBar.Increase);
myProcessBar.ShowDialog();
myProcessBar = null;
}
在子執行緒中,先透過 BeginInvoke 非同步呼叫 ShowProcessBar 開啟視窗,稍作延遲確保視窗顯示,隨後透過 Invoke 同步呼叫委托更新進度,直到進度條達到最大值為止。
private void ThreadFun()
{
MethodInvoker mi = new MethodInvoker(ShowProcessBar);
this.BeginInvoke(mi);
Thread.Sleep(1000); // 等待視窗顯示
bool blnIncreased = false;
object objReturn = null;
do
{
Thread.Sleep(50);
objReturn = this.Invoke(this.myIncrease, new object[] { 2 });
blnIncreased = (bool)objReturn;
}
while (blnIncreased);
}
關鍵差異在於 BeginInvoke 不阻塞執行緒,而 Invoke 會等待方法完成。透過委托回傳值判斷進度是否結束,若需更多控制可擴充委托簽章。
最後在需要處的程式碼中啟動子執行緒:
Thread thdSub = new Thread(new ThreadStart(ThreadFun));
thdSub.Start();
如此即完成一個以模態視窗呈現進度條的完整範例。