?
二.給窗體添加屬性或方法
?
1.使用Form類的Owner屬性
?
獲取或設(shè)置擁有此窗體的窗體。若要使某窗體歸另一個(gè)窗體所有,請(qǐng)為其 Owner 屬性分配一個(gè)對(duì)將成為所有者的窗體的引用。當(dāng)一個(gè)窗體歸另一窗體所有時(shí),它便隨著所有者窗體最小化和關(guān)閉。例如,如果 Form2 歸窗體 Form1 所有,則關(guān)閉或最小化Form1 時(shí),也會(huì)關(guān)閉或最小化 Form2。并且附屬窗體從不顯示在其所有者窗體后面。可以將附屬窗體用于查找和替換窗口之類的窗口,當(dāng)選定所有者窗體時(shí),這些窗口不應(yīng)消失。若要確定某父窗體擁有的窗體,請(qǐng)使用OwnedForms屬性。
?
上面是SDK幫助文檔上講的,下面我們就來使用它。
?
?
首先還是使用第一篇文章中的第二個(gè)例子,窗體如下:
說明:在這個(gè)例子中我們的兩個(gè)窗體都加了一個(gè)ListBox用來顯示ArrayList中的內(nèi)容。
?
主窗體中控件:listBoxFrm1,buttonEdit;
?
子窗體中控件:listBoxFrm2,textBoxAdd,buttonAdd,buttonEdit,buttonOK。
?
主窗體中還是定義類數(shù)據(jù)成員,
?
private ArrayList listData1;
?
在構(gòu)造函數(shù)里實(shí)例化它,填充數(shù)據(jù),最后綁定到listBoxFrm1。
?
構(gòu)造函數(shù)如下:
?
public Form1()
?
{
?
???? InitializeComponent();
?
???? this.listData1 = new ArrayList();
?
???? this.listData1.Add("DotNet");
?
???? this.listData1.Add("C#");
?
???? this.listData1.Add("Asp.net");
?
???? this.listData1.Add("WebService");
?
???? this.listData1.Add("XML");
?
???? this.listBoxFrm1.DataSource = this.listData1;
?
}
?
主窗體的修改按鈕處理函數(shù):
?
private void buttonEdit_Click(object sender, System.EventArgs e)
?
{
?
???? Form2 formChild = new Form2();
?
???? formChild.Owner = this;
?
???? formChild.ShowDialog();
?
???? this.listBoxFrm1.DataSource = null;
?
???? this.listBoxFrm1.DataSource = this.listData1;
?
}
?
我們?cè)O(shè)置了formChild.Owner為this,這樣,子窗體和主窗體就有聯(lián)系了,
?
當(dāng)然我們也可以改成如下:
?
private void buttonEdit_Click(object sender, System.EventArgs e)
?
{
?
???? Form2 formChild = new Form2();
?
???? formChild.ShowDialog(this);
?
???? this.listBoxFrm1.DataSource = null;
?
???? this.listBoxFrm1.DataSource = this.listData1;
?
}
?
不過這樣還不行,目前主窗體的listData1變量外部訪問不到,
?
private ArrayList listData1;
?
必須修改為public訪問修飾符,
?
public ArrayList listData1;
?
也可以通過屬性(property)來實(shí)現(xiàn),
?
public ArrayList ListData1
?
{
?
???? get{return this.listData1;}
?
}
?
這里我采用屬性,感覺語法更靈活,清楚。
?
下面是對(duì)Form2的修改,
?
構(gòu)造函數(shù)又恢復(fù)原貌了。
?
public Form2()
?
{
?
???? InitializeComponent();
?
}
?
另外又新增了一個(gè)窗體的Load事件,在它的事件處理函數(shù)中來獲取主窗體中的數(shù)據(jù),
?
private void Form2_Load(object sender, System.EventArgs e)
?
{
?
???? Form1 pareForm = (Form1)this.Owner;
?
???? this.listData2 = pareForm.ListData1;
?
???? foreach(object o in this.listData2)
?
???????? this.listBoxFrm2.Items.Add(o);
?
}
?
有人會(huì)問,為什么不把上面的代碼放到構(gòu)造函數(shù)里面去呢?如下不是更好,
?
public Form2()
?
{
?
???? InitializeComponent();
?
?? ??Form1 pareForm = (Form1)this.Owner;
?
???? this.listData2 = pareForm.ListData1;
?
???? foreach(object o in this.listData2)
?
???????? this.listBoxFrm2.Items.Add(o);
?
}
?
那我會(huì)對(duì)你說錯(cuò)了,因?yàn)樵谥鞔绑w修改按鈕被點(diǎn)擊后,開始執(zhí)行
?
Form2 formChild = new Form2();
?
而在Form2的實(shí)例化過程中會(huì)在構(gòu)造函數(shù)中執(zhí)行
?
Form1 pareForm = (Form1)this.Owner;
?
而這時(shí)的this.Owner是沒有值的,為空引用,那么下面的代碼肯定也出問題,
?
this.listData2 = pareForm.ListData1;
?
foreach(object o in this.listData2)
?
???? this.listBoxFrm2.Items.Add(o);
?
當(dāng)整個(gè)Form2實(shí)例化完成后,才會(huì)執(zhí)行
?
formChild.Owner = this;
?
這條代碼,所以使用了Form2_Load事件。
?
那怎樣可以不使用Form2_Load事件呢?等下面我們來修改代碼實(shí)現(xiàn)它。
?
下面的子窗體代碼沒有變化,
?
private void buttonAdd_Click(object sender, System.EventArgs e)
?
{
?
???? if(this.textBoxAdd.Text.Trim().Length>0)
?
???? {
?
???????? this.listData2.Add(this.textBoxAdd.Text.Trim());
?
???????? this.listBoxFrm2.Items.Add(this.textBoxAdd.Text.Trim());
?
???? }
?
???? else
?
???????? MessageBox.Show("請(qǐng)輸入添加的內(nèi)容!");
?
}
?
private void buttonDel_Click(object sender, System.EventArgs e)
?
{
?
???? int index = this.listBoxFrm2.SelectedIndex;
?
???? if(index!=-1)
?
???? {
?
???????? this.listData2.RemoveAt(index);
?
???????? this.listBoxFrm2.Items.RemoveAt(index);
?
???? }
?
???? else
?
???????? MessageBox.Show("請(qǐng)選擇刪除項(xiàng)!");
?
}
?
private void buttonOK_Click(object sender, System.EventArgs e)
?
{
?
???? this.Close();
?
}
?
好了,結(jié)果同第一篇中的一樣,子窗體能修改主窗體的值。
?
2.使用自定義屬性或方法
?
下面我們來講講怎樣使用自定義屬性或方法來完成數(shù)據(jù)修改功能而不使用Form2_Load事件。
?
主窗體的修改按鈕點(diǎn)擊處理函數(shù)如下:
?
private void buttonEdit_Click(object sender, System.EventArgs e)
?
{
?
???? Form2 formChild = new Form2();
?
??? ?formChild.ListData2 = this.listData1;
?
???? formChild.ShowDialog();
?
???? this.listBoxFrm1.DataSource = null;
?
???? this.listBoxFrm1.DataSource = this.listData1;
?
}
?
并且我們?nèi)サ袅酥鞔绑w的ListData1屬性,
?
//public ArrayList ListData1
?
//{
?
//?? get{return this.listData1;}
?
//}
?
而在子窗體中加上ListData2屬性,
?
public ArrayList ListData2
?
{
?
???? set
?
???? {
?
???????? this.listData2 = value;
?
???????? foreach(object o in this.listData2)
?
????????????? this.listBoxFrm2.Items.Add(o);
?
???? }
?
}
?
也可以把屬性改成方法,
?
public void SetListData(ArrayList listData)
?
{
?
???? this.listData2 = listData;
?
???? foreach(object o in this.listData2)
?
???????? this.listBoxFrm2.Items.Add(o);
?
}
?
而在主窗體的修改按鈕處理函數(shù)中也要相應(yīng)改動(dòng):
?
formChild.ListData2 = this.listData1;
?
改為
?
formChild.SetListData(this.listData1);
?
???? 總結(jié),我們通過Form類的Owner屬性來建立主從窗體間的橋梁,這個(gè)是不是類似于把主窗體作為子窗體的構(gòu)造函數(shù)參數(shù)傳入實(shí)現(xiàn)的功能差不多;另外又采用了屬性和方法來完成數(shù)據(jù)的交互,我覺得這種實(shí)現(xiàn)方法很實(shí)用,特別是用在不需要實(shí)例化類或著已經(jīng)有了實(shí)例的情況下傳遞數(shù)據(jù)。