在.net中輕鬆掌握Windows表單間的資料互動(一)
最後更新:2017-02-28
來源:互聯網
上載者:User
window|互動|資料 在.net中輕鬆掌握Windows表單間的資料互動(一)
zhzuo(秋楓)
Windows 表單是用於 Microsoft Windows 應用程式開發的、基於 .NET Framework 的新平台。此架構提供一個有條理的、物件導向的、可擴充的類集,它使您得以開發豐富的 Windows 應用程式。一個Windows表單就代表了.NET架構裡的System.Windows.Forms.Form類的一個執行個體。
作者在CSDN技術論壇.NET板塊下的C#分類經常看到有人問起如何在兩個Form間傳遞資料,訪問修改對方表單裡面的值。對於有經驗的程式員來說不是什麼高深的東西,而對於初學者來說這些基礎的東西往往是一個問題,並且存在這種現象,往往比較複雜的東西他們會,要用什麼了就去學什麼,實際上並沒有真正的去理解掌握它,基礎不紮實,所以就有了想通過自己對表單編程積累的經驗來寫一些這方面的文章,以供學.NET的朋友參考,也藉此機會同各位朋友進行交流,寫得不合理的地方請各位朋友提寶貴意見,下面我分了三個部分來講。
一.使用帶參數的建構函式
我們要做的準備工作就是建立兩個表單,下面是兩個表單的布局,很簡單:
<第一個例子>
說明:Form1為主表單,包含控制項:文字框textBoxFrm1,多選框checkBoxFrm1和按鈕buttonEdit;
Form2為子表單,包含控制項:文字框textBoxFrm2,多選框checkBoxFrm2和按鈕buttonOK,buttonCancel。
當我們建立一個表單的時候,設計器會產生預設的建構函式:
public Form2()
{
InitializeComponent();
}
它不帶參數,既然我們要把Form1中的一些資料傳到Form2中去,為什麼不在Form2的建構函式裡做文章呢?
假設我們要實現使Form2中的文字框顯示Form1裡textBoxFrm1的值,修改子表單的建構函式:
public Form2(string text)
{
InitializeComponent();
this.textBoxFrm2.Text = text;
}
增加Form1中的修改按鈕點擊事件,處理函數如下:
private void buttonEdit_Click(object sender, System.EventArgs e)
{
Form2 formChild = new Form2(this.textBoxFrm1.Text);
formChild.Show();
}
我們把this.textBoxFrm1.Text作為參數傳到子表單建構函式,以非模式方式開啟,這樣開啟的formChild的文字框就顯示了”主表單”文本,是不是很簡單,接下來我們傳一個boolean資料給子表單。
Public Form2(string text,bool checkedValue)
{
InitializeComponent();
this.textBoxFrm2.Text = text;
this.checkBoxFrm2.Checked = checkedValue;
}
在主表單中的修改按鈕點擊處理,我採用了開啟強制回應視窗的方式,其實在這個例子中看不出有什麼分別,
private void buttonEdit_Click(object sender, System.EventArgs e)
{
Form2 formChild = new Form2(this.textBoxFrm1.Text,this.checkBoxFrm1.Checked);
formChild.ShowDialog();
}
結果在預料之中,但是這裡明顯存在不足,在子表單裡的資料修改後不能傳給主表單,也就是說主表單不受子表單的影響。而在實際的開發過程中我們經常使用子表單來修改主表單裡面的資料,那怎麼解決呢?
在.NET中有兩種類型,實值型別和參考型別。實值型別是從ValueType繼承而來,而ValueType又是從Object繼承;對於參考型別它直接繼承Object類型。這下讓我們看看怎樣通過Form2來修改Form1裡的資料。
還是讓我們來修改Form2的代碼。
Private TextBox textBoxFrm12;
private CheckBox checkBoxFrm12;
public Form2(TextBox heckbo,CheckBox heckbox)
{
InitializeComponent();
this.textBoxFrm2.Text = heckbo.Text;
this.checkBoxFrm2.Checked = heckbox.Checked;
this.textBoxFrm12 = heckbo;
this.checkBoxFrm12 = heckbox;
}
現在我們傳了兩個參考型別的資料:TextBox類型,和CheckBox;另外在Form2中增加了兩個類資料成員textBoxFrm12、checkBoxFrm12用來分別儲存建構函式傳來的變數,不過他們並不屬於Form2的Controls容器。修改Form2的確定按鈕點擊事件函數:
private void buttonOK_Click(object sender, System.EventArgs e)
{
this.textBoxFrm12.Text = this.textBoxFrm2.Text;
this.checkBoxFrm12.Checked = this.checkBoxFrm2.Checked;
this.Close();
}
上面的代碼我們通過把textBoxFrm2的Text和checkBoxFrm2.Checked賦給textBoxFrm12和checkBoxFrm12完成了對主表單中的textBoxFrm1和checkBoxFrm2的修改,因為textBoxFrm1和textBoxFrm12是同一個引用,而checkBoxFrm2和checkBoxFrm12也是。
到這裡為止功能是實現了,但是總覺得不是很合理,讓兩個表單控制項傳來傳去,現在我舉一個恰當一點的例子。
修改了兩個表單:
<第二個例子>
說明:在這個例子中我們的兩個表單都加了一個ListBox用來顯示ArrayList中的內容。
主表單中控制項:listBoxFrm1,buttonEdit;
子表單中控制項:listBoxFrm2,textBoxAdd,buttonAdd,buttonEdit,buttonOK。
這次我們用ArrayList來作為傳遞資料,在Form1中定義類資料成員:
private ArrayList listData1;
在建構函式中增加了對listData1進行記憶體配置,並產生資料最終綁定到listBoxFrm1,
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;
}
另外,對修改按鈕點擊事件處理函數的修改如下:
private void buttonEdit_Click(object sender, System.EventArgs e)
{
Form2 formChild = new Form2(this.listData1);
formChild.ShowDialog();
this.listBoxFrm1.DataSource = null;
this.listBoxFrm1.DataSource = this.listData1;
}
相對與主表單,對子表單作相應修改,也在Form2中增加了類資料成員:
private ArrayList listData2;
用來儲存對主表單中listData1的引用。
修改建構函式:
public Form2(ArrayList listData)
{
InitializeComponent();
this.listData2 = listData;
foreach(object o in this.listData2)
{
this.listBoxFrm2.Items.Add(o);
}
}
這裡讓listData2同listData1指向同一個引用;另外沒有對listBoxFrm進行綁定,採用了填充。
好了,下面是對資料操作的時候了。
添加處理函數代碼如下:
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("請輸入添加的內容!");
}
刪除處理代碼如下:
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("請選擇刪除項或者沒有可刪除的項!");
}
退出Form2子表單:
private void buttonOK_Click(object sender, System.EventArgs e)
{
this.Close();
}
編譯運行程式,在子表單中對資料進行修改,關閉後,主表單就會顯示更新後的資料。
這裡有一點要提醒一下,比較兩個例子,我們都傳的是參考型別,一個是String,另一個是ArrayList,為什麼string類型不能修改主表單的資料呢?其實在.Net中對string類型的修改並不是修改原來的值,原來的值沒有變化,而是重建一個新的字串,下面是一個很好的說明。
public class ZZConsole
{
[STAThread]
static void Main(string[] args)
{
string str1 = "abc";
string str2 = str1;
str1 = "123";
Console.WriteLine(str1);
Console.WriteLine("--------------");
Console.WriteLine(str2);
Console.WriteLine("--------------");
ArrayList al1 = new ArrayList();
al1.Add("abc");
ArrayList al2 = al1;
al2.Add("123");
foreach(object o in al1)
Console.WriteLine((string)o);
Console.WriteLine("--------------");
foreach(object o in al2)
Console.WriteLine((string)o);
Console.ReadLine();
}
}
運行一下看看輸出結果就明白了,另外對實值型別的資料操作要使用ref關鍵字。
總結,我們通過帶參數的建構函式實現了表單間的資料互動,代碼看上去也比較清楚,在實際開發過程中,可以把DataSet,DataTable,或者是DataView當作參數,當然如果只是想修改一行,可以傳個DataRow或者DataRowView。在下面的文章中我們來看看怎樣使用另外兩種方法來實現資料的互動。