對於表單間的資料傳遞,是剛開始從事.Net表單應用程式開發人員碰到的一個常見問題,在此講幾個常見的實現方式。此節內容適用於模式表單或非模式表單,部分方式延伸到一般類的操作。
(1)建構函式參數傳遞
通過建構函式傳遞參數應該是比較基本的參數傳遞方式,重載建構函式,通過帶參數的建構函式來執行個體化表單。
在表單類內部定義參數變數,
private object myParams;
實現建構函式,
public OptionForm(object parameters)
{
InitializeComponent();
this.myParams = parameters;//設定參數引用
}
執行個體化表單,
OptionForm form = new OptionForm( myParams );
在實際使用過程中,需要注意傳入的是參考型別還是實值型別,處理方式會有所不同。
(2)使用表單的屬性
說起屬性關聯,上面已經提到過Form.Owner屬性,下面筆者根據MSDN文檔來比較完整的講一下,大部分的文字來自MSDN文檔,為保證其完整性,對其中一些屬性描述進行了擴充。
Form.Owner 屬性。擷取或設定擁有此表單的表單。
文法,public Form Owner { get; set; }
若要使某表單歸另一個表單所有,可為其 Owner 屬性分配一個對將成為所有者的表單的引用。當一個表單歸另一表單所有時,它便隨著所有者表單最小化和關閉。例如,如果 Form2 歸表單 Form1 所有,則關閉或最小化 Form1 時,Form2 也會關閉或最小化。並且附屬表單從不顯示在其所有者表單後面。可以將附屬表單用於尋找和替換視窗之類的視窗,當選定所有者表單時,這些視窗不應消失。
Form.OwnedForms 屬性。擷取 Form 對象的數組,這些對象表示此表單擁有的所有表單。
文法,public Form[] OwnedForms { get; }
此屬性返回包含此表單擁有的所有表單的數組。要使某表單歸另一個表單所有,可調用 AddOwnedForm 方法。分配給所有者表單的表單將保持被擁有狀態,直到調用了 RemoveOwnedForm 方法。如果表單是多重文件介面 (MDI) 父表單,則除了當前開啟的所有 MDI 子表單外,此屬性將返回所有顯示的表單。
Form.MdiChildren 屬性。擷取表單的數組,這些表單表示以此表單作為父級的多重文件介面 (MDI) 子表單。
文法,public Form[] MdiChildren { get; }
此屬性使您得以擷取對當前在某 MDI 父表單中開啟的所有 MDI 子表單的引用。若要建立 MDI 子表單,請將要成為 MDI 父表單的 Form 分配給該子表單的 MdiParent 屬性。可以使用此屬性依次通過所有 MDI 子表單,以執行一些操作,如當 MDI 父表單關閉時將資料儲存到資料庫中,或者根據應用程式中執行的操作更新子表單上的欄位。
Form.MdiParent 屬性。擷取或設定此表單的當前多重文件介面 (MDI) 父表單。
文法,public Form MdiParent { get; set; }
若要建立 MDI 子表單,請將要成為 MDI 父表單的 Form 分配給該子表單的 MdiParent 屬性。可以從某 MDI 子表單使用此屬性來擷取所有子表單都需要的全域資訊或者調用對所有子表單執行操作的方法。
Form.ActiveForm 靜態屬性。擷取此應用程式的當前活動表單。
文法,public static Form ActiveForm { get; }
表示當前活動表單,或者如果沒有活動表單,則為空白引用。可以使用此方法獲得對當前活動表單的引用,以在該表單或其控制項上執行操作。
Form.ActiveMdiChild 屬性。擷取當前活動的多重文件介面 (MDI) 子視窗。
文法,public Form ActiveMdiChild { get; }
返回表示當前活動的 MDI 子視窗的 Form,或者如果當前沒有子視窗,則返回 Null 參考。可使用此方法確定 MDI 應用程式中是否有任何開啟的 MDI 子表單。也可使用此方法從 MDI 子視窗的 MDI 父表單或者從應用程式中顯示的其他表單對該 MDI 子視窗執行操作。
ContainerControl.ParentForm 屬性。擷取將容器控制項分配給的表單。
文法,public Form ParentForm { get; }
將容器控制項分配給的 Form。
(3)使用公用屬性(念時註:我比較常用這種方式)
使用公用屬性也是一種比較常用的方式,通過表單設計器添加的控制項預設存取修飾詞為private層級,可以設定成public或Internal(在程式集內部可見)來對外公開。比如對表單中的Button進行公開,那就可以訪問Button的相關屬性,同時也可以註冊事件或撤銷事件註冊。如,
OptionForm form = new OptionForm();
form.buttonOK.Click += new EventHandler(buttonOK_Click);
form.ShowDialog();
對於只允許讀取存取或修改訪問的控制項或變數可以通過屬性來控制。對(1)方式進行修改,去除重載建構函式,增加屬性也可以實現同樣的效果。
public object MyParams
{
get { return this.myParams; }
set { this.myParams = value; }
}
(4)使用公用方法
使用公用方法類似於屬性,對上面的同等實現如下,
//擷取參數
public object GetParams()
{
return this.myParams;
}
//設定參數
public void SetParams(object myParams )
{
this.myParams = myParams;
}
(5)使用靜態類該方式可以簡單的理解為靜態變數全域共用,通過下面代碼能夠比較清楚的理解,先來定義靜態類,
public static class ParameterSettings
{
//公用靜態變數
public static string Username = "Zhengzuo";
//私人靜態變數
private static string userRole = "Administrators";
//私人靜態變數
private static string password = "http://blog.csdn.net/zhzuo";
//內部屬性
internal static string UserRole
{
get { return userRole; }
}
//公用屬性
public static string Password
{
get { return password; }
private set { password = value; }
}
}
在需要訪問的地方通過以下方式進行,
string username = ParameterSettings.Username;
string password = ParameterSettings.Password;
string userRole = ParameterSettings.UserRole;
ParameterSettings.Username = "鄭佐";//修改成新使用者名稱
(6)表單實現Singleton模式
Singleton模式是我們開發過程中最常用的模式之一。在技術社區經常看到有人談及對主表單實現Singleton,但個人認為這不是一種妥當的做法,因為沒有這個必要。這裡通過另一個自訂類來進行示範。假設UserLoginInfo類用來儲存登入系統後的使用者憑證。
/*==============================================
程式 鄭佐 2006-4-23 http://blog.csdn.net/zhzuo
==============================================*/
public class UserLoginInfo
{
//實現Singleton模式,安全執行緒。
private readonly static UserLoginInfo currentUserInfo = new UserLoginInfo();
//提供全域訪問點
public static UserLoginInfo CurrentUserInfo
{
get { return currentUserInfo; }
}
//阻止顯式執行個體化,但不能阻止反射方式調用。
private UserLoginInfo()
{
}
//公開變數
public string Username;
//私人變數
private static string userRole;
//私人變數
private static string password;
//內部屬性
internal string UserRole
{
get { return userRole; }
set { userRole = value; }
}
//公用屬性
public string Password
{
get { return password; }
internal set { password = value; }
}
}
在其他代碼中進行訪問,
UserLoginInfo.CurrentUserInfo.Username ="鄭佐";
UserLoginInfo.CurrentUserInfo.UserRole = "dotnetlover";
UserLoginInfo.CurrentUserInfo.Password = "http://blog.csdn.net/zhzuo";
對於Singleton模式的實現方式有很多,編寫時需要考慮是否需要保證執行個體訪問的安全執行緒問題,以免引發不可預料的情況,為了提高效能可以考慮惰性執行個體化。關於Singleton模式的更多資訊可以參考另一篇文章。
(7)發布事件進行訂閱
通過事件來傳遞參數應該說是一種推的實現方式,在產生事件時進行被動的擷取相關資料。這裡將通過一個自訂事件來示範資料的傳輸。
在自訂事件時,標準的做法都會先定義一個事件參數類,要麼直接使用基類EventArgs,或者從EventArgs繼承實現自己的參數類,假設自訂基類取名為OptionSettingEventArgs,
//選項設定事件參數類
public class OptionSettingEventArgs : EventArgs
{
private string changedPath;
//建構函式
public OptionSettingEventArgs(string changedPath)
{
this.changedPath = changedPath;
}
//讀取參數
public string ChangedPath
{
get { return this.changedPath; }
}
}
以上參數類只包含一個修改後的路徑參數。接下去我們要對原先的OptionForm表單增加事件定義,這裡使用.net 2.0中提供的泛型類來實現。
//定義事件
public event EventHandler<OptionSettingEventArgs>
OptionSettingChanged;
編寫事件引發程式如下,
//引發OptionSettingChanged事件
protected virtual void OnOptionSettingChanged(OptionSettingEventArgs e)
{
if (OptionSettingChanged != null)
{
OptionSettingChanged(this, e);
}
}
對檔案目錄選擇按鈕事件處理常式進行修改來實現事件激發,並沒有考慮直接從文字框直接資料輸入方式。
//通過目錄對話方塊設定新的路徑
private void buttonBrowser_Click(object sender, EventArgs e)
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
DialogResult result = dialog.ShowDialog(this);
if (result == DialogResult.OK)
{
if(this.textBoxPath.Text != dialog.SelectedPath)
{
this.textBoxPath.Text = dialog.SelectedPath;
OptionSettingEventArgs args = new OptionSettingEventArgs(dialog.SelectedPath);
OnOptionSettingChanged(args);
}
}
}
好了,一切準備工作完成,調用代碼如下,
OptionForm form = new OptionForm();
//註冊事件
form.OptionSettingChanged += new EventHandler
(form_OptionSettingChanged);
form.ShowDialog();
通過以下事件處理常式來驗證其正確性,
private void form_OptionSettingChanged(object sender, OptionSettingEventArgs e)
{
string newPath = e.ChangedPath;
MessageBox.Show(this, String.Format("新路徑為“{0}”。", newPath), "提示");
}
不知大家讀了之後覺得怎麼樣,我覺得受益匪淺,感覺講得很仔細,很全面,而且通俗易懂,希望你們也能有同樣的感受。
轉載自‘中國IT實驗室’原文作者:鄭佐