這個問題會讓一些初學者感到困惑,一方面模態表單在開啟之後(Form.ShowDialog).主線程無法繼續執行下面的事務;另一方面,又要在處理事務的時候來同步這個表單裡面的進度條。這兩件事情都必須做,卻都不能先做...
所以很多人不得不把交易處理寫到模態表單當中去,這樣可以達到目的,卻造成了代碼結構混亂,而且子表單無法複用,如果有多個事物,不得不為每個事務來寫控制表單。
這裡我們介紹一種比較直接了當的方法,就是主線程中開啟兩個子線程,一個用於顯示模態表單,一個用於處理事務, 並同時更新第一個線程中的表單資訊。
這裡的知識範疇會包含線程的基礎用法,線程和UI之間的互動,以及委託的基本用法。如果你還不瞭解這幾點,可以參考一些其他資料,比如我先前寫過的,在同一表單中用子線程來控制進度條
http://blog.csdn.net/jinjazz/archive/2008/05/06/2397136.aspx
這裡的應用稍微複雜一些,你可以先用Vs2005建立一個Windows Application,這個application包含兩個表單,一個Form1,為主表單,一個Form2,為模態子表單。Form1,中添加Button1,用來開啟測試。Form2中添加進度條ProgressBar1和一個用來取消事務的按鈕Button1。然後把如下代碼貼入測試程式中的兩個form裡面。
Form1,主表單
using
System;
using
System.Windows.Forms;
namespace
WindowsApplication39
...
{
public
partial
class
Form1 : Form
...
{
delegate
void
dShowForm();
Form2 frm
=
new
Form2();
public
Form1()
...
{
this
.InitializeComponent();
}
//
顯示表單
void
ShowForm()
...
{
if
(
this
.InvokeRequired)
...
{
this
.Invoke(
new
dShowForm(
this
.ShowForm));
}
else
...
{
frm.ShowDialog(
this
);
}
}
//
控制進度
void
SetProgress()
...
{
for
(
int
i
=
1
; i
<=
100
; i
++
)
...
{
if
(frm.DialogResult
==
DialogResult.Cancel)
...
{
//
判斷取消
break
;
}
else
...
{
//
類比進度
frm.SetProgress(
100
, i);
System.Threading.Thread.Sleep(
50
);
}
}
}
private
void
button1_Click(
object
sender, EventArgs e)
...
{
new
System.Threading.Thread(
new
System.Threading.ThreadStart(ShowForm)).Start();
new
System.Threading.Thread(
new
System.Threading.ThreadStart(SetProgress)).Start();
}
}
}
Form2,模態表單
using
System;
using
System.Windows.Forms;
namespace
WindowsApplication39
...
{
public
partial
class
Form2 : Form
...
{
public
Form2()
...
{
InitializeComponent();
}
public
delegate
void
dSetProgress(
int
total,
int
current);
public
void
SetProgress(
int
total,
int
current)
...
{
if
(
this
.InvokeRequired)
...
{
try
...
{
this
.Invoke(
new
dSetProgress(
this
.SetProgress),
new
object
[]
...
{ total, current }
);
}
catch
...
{ }
}
else
...
{
this
.progressBar1.Maximum
=
total;
this
.progressBar1.Value
=
current;
}
}
private
void
button1_Click(
object
sender, EventArgs e)
...
{
this
.DialogResult
=
DialogResult.Cancel;
}
}
}