原始碼下載請點這裡
在設計表單程式時往往需要相互調用的表單間傳遞複雜的資料,有時候甚至需要子表單修改父表單的內容。前一陣在部落格園中看到很多人討論這個問題,在海天一鷗《表單間傳值和表單間互操作》的評論中,我看到有這麼幾種做法:1)公開一個靜態變數;2)在子表單中建立一個公有欄位;3)在父表單中使用委託與事件;4)將子表單作為父表單成員。
這些辦法我感覺都不是特別好,會導致父表單與子表單耦合過於緊密,對任何一個表單的修改需要重新編譯另外一個表單。根據“依賴倒置”的原則,通過引 入一個結果對象,就可以避免這種緊耦合,同時也可以傳遞任意複雜的資料。如果需要在子表單中改變父表單狀態,也可以在這個結果對象中定義委託與事件來達到 目的。我在這裡給出我的解決方案。
首先定義一個結果對象,用來存放子表單返回的結果。同時定義一些事件,可以讓子表單修改父表單的狀態。代碼如下:
using System;
namespace WinParam
{
public delegate void TextChangedHandler(string s);
public class cResult
{
public string Result1 = "";
public string Result2 = "";
public event TextChangedHandler TextChanged;
public void ChangeText(string s)
{
if(TextChanged != null)
TextChanged(s);
}
}
}
添加一子表單建構函式,允許接收一結果對象:
private cResult r;
public frmChild(cResult r):this()
{
this.r = r;
}
在父表單中建立子表單,並訂閱cResult事件:
private void btnCallChild_Click(object sender, System.EventArgs e)
{
cResult r = new cResult();
r.TextChanged += new TextChangedHandler(this.EventResultChanged);
frmChild fc = new frmChild(r);
fc.ShowDialog();
txtCallResult.Text = "The Result is: " + r.Result1 + " " + r.Result2;
}
private void EventResultChanged(string s)
{
txtEventResult.Text = s;
}
這樣確保父表單知道子表單,而子表單不知道父表單。父表單改變後不需要重新編譯子表單。同時兩個表單都依賴於結果對象,結果對象的穩定性也決定了父表單與子表單關係的穩定性。下面是程式運行結果:
註:提供的代碼僅僅是功能示範,如果實際使用需要添加一些額外輔助代碼(對象釋放、取消事件訂閱等)。