blavince's BLOG

Giving is a reward in itself.

0%

Winform UI 客製化(四) - 委派

視窗程式開發時, 為避免執行時間較長的函數將視窗凍結而使用執行緒 (Threading) 執行函數, 但執行緒和視窗元件互動卻發生跨執行緒間的存取權限問題 (※建立視窗元件的執行緒與使用的執行緒不同).

前言

為了避免跨執行緒間的視窗元件操作問題, 使用委派 (Delegate) 來處理這類問題.

本文

委派的寫法像替元件寫個 Callback, 判斷是不是在同一個執行緒內, 如果 不是 則呼叫 Callback Function (底下 if 區塊內), 如果 則將需求完成.

Sample Code

  1. 更新 comboBox 的狀態:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private delegate void ComboBox_update(bool status);

private void combobox_update(bool status)
{
if (this.InvokeRequired)
{
ComboBox_update myUpdate = new ComboBox_update(combobox_update);
this.Invoke(myUpdate, status);
}
else
{
comboBox_project.Enabled = status;
}
}

private void button1_Click(object sender, EventArgs e)
{
combobox_update(true);
}

或者
2. 更新 textBox 的狀態:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public void update_msg_windows(string msg)
{
string t = DateTime.Now.ToString("MM/dd HH:mm:ss.fff ");

if (txtBox_msg_window.InvokeRequired)
{
Action<string> actionDelegate = (x) =>
{
this.txtBox_msg_window.AppendText(x.ToString());
};
this.txtBox_msg_window.Invoke(actionDelegate, t + msg + "\r\n");
}
else
{
txtBox_msg_window.AppendText(t + msg + "\r\n");
txtBox_msg_window.Refresh();
}
break;

}

private void button1_Click(object sender, EventArgs e)
{
update_msg_windows("Hello World!");
}
  1. 更新 RichBox 的狀態:

甚至透過重載實現 輸出預設顏色 或者 改變顏色的訊息,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//輸出預設顏色訊息
public void AppendRichBoxLog(string msg)
{
try
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(AppendRichBoxLog), new object[] { msg });
return;
}

DateTime dt = DateTime.Now;
richTextBox_log.AppendText(dt.ToString("yyyy/MM/dd HH:mm:ss") + " " + msg + "\r\n");
richTextBox_log.ScrollToCaret();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}

//輸出顏色 textColor 訊息
public void AppendRichBoxLog(string msg, Color textColor)
{
try
{
if (InvokeRequired)
{
this.Invoke(new Action<string, Color>(AppendRichBoxLog), new object[] { msg, textColor });
return;
}

DateTime dt = DateTime.Now;
Color _r = richTextBox_log.SelectionColor;
richTextBox_log.SelectionColor = textColor;
richTextBox_log.AppendText(dt.ToString("yyyy/MM/dd HH:mm:ss") + " " + msg + "\r\n");
richTextBox_log.SelectionColor = _r;
richTextBox_log.ScrollToCaret();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}