Windows 窗體是用於 Microsoft Windows 應用程序開發的基於 NET Framework 的新平台此框架提供一個有條理的面向對象的可擴展的類集它使您得以開發豐富的 Windows 應用程序一個Windows窗體就代表了NET架構裡的SystemWindowsFormsForm類的一個實例
作者在CSDN技術論壇NET板塊下的C#分類經常看到有人問起如何在兩個Form間傳遞數據訪問修改對方窗體裡面的值對於有經驗的程序員來說不是什麼高深的東西而對於初學者來說這些基礎的東西往往是一個問題並且存在這種現象往往比較復雜的東西他們會要用什麼了就去學什麼實際上並沒有真正的去理解掌握它基礎不扎實所以就有了想通過自己對窗體編程積累的經驗來寫一些這方面的文章以供學NET的朋友參考也借此機會同各位朋友進行交流寫得不合理的地方請各位朋友提寶貴意見下面我分了三個部分來講
一.使用帶參數的構造函數
我們要做的准備工作就是新建兩個窗體下面是兩個窗體的布局很簡單
<第一個例子>
說明Form為主窗體包含控件文本框textBoxFrm多選框checkBoxFrm和按鈕buttonEdit
Form為子窗體包含控件文本框textBoxFrm多選框checkBoxFrm和按鈕buttonOKbuttonCancel
當我們新建一個窗體的時候設計器會生成默認的構造函數
public Form()
{
InitializeComponent();
}
它不帶參數既然我們要把Form中的一些數據傳到Form中去為什麼不在Form的構造函數裡做文章呢?
假設我們要實現使Form中的文本框顯示Form裡textBoxFrm的值修改子窗體的構造函數
public Form(string text)
{
InitializeComponent();
thistextBoxFrmText = text;
}
增加Form中的修改按鈕點擊事件處理函數如下
private void buttonEdit_Click(object sender SystemEventArgs e)
{
Form formChild = new Form(thistextBoxFrmText);
formChildShow();
}
我們把thistextBoxFrmText作為參數傳到子窗體構造函數以非模式方式打開這樣打開的formChild的文本框就顯示了主窗體文本是不是很簡單接下來我們傳一個boolean數據給子窗體
Public Form(string textbool checkedValue)
{
InitializeComponent();
thistextBoxFrmText = text;
thischeckBoxFrmChecked = checkedValue;
}
在主窗體中的修改按鈕點擊處理我采用了打開模式窗口的方式其實在這個例子中看不出有什麼分別
private void buttonEdit_Click(object sender SystemEventArgs e)
{
Form formChild = new Form(thistextBoxFrmTextthischeckBoxFrmChecked);
formChildShowDialog();
}
結果在預料之中但是這裡明顯存在不足在子窗體裡的數據修改後不能傳給主窗體也就是說主窗體不受子窗體的影響而在實際的開發過程中我們經常使用子窗體來修改主窗體裡面的數據那怎麼解決呢?
在NET中有兩種類型值類型和引用類型值類型是從ValueType繼承而來而ValueType又是從Object繼承對於引用類型它直接繼承Object類型這下讓我們看看怎樣通過Form來修改Form裡的數據
還是讓我們來修改Form的代碼
Private TextBox textBoxFrm;
private CheckBox checkBoxFrm;
public Form(TextBox heckboCheckBox heckbox)
{
InitializeComponent();
thistextBoxFrmText = heckboText;
thischeckBoxFrmChecked = heckboxChecked;
thistextBoxFrm = heckbo;
thischeckBoxFrm = heckbox;
}
現在我們傳了兩個引用類型的數據TextBox類型和CheckBox另外在Form中增加了兩個類數據成員textBoxFrmcheckBoxFrm用來分別保存構造函數傳來的變量不過他們並不屬於Form的Controls容器修改Form的確定按鈕點擊事件函數
private void buttonOK_Click(object sender SystemEventArgs e)
{
thistextBoxFrmText = thistextBoxFrmText;
thischeckBoxFrmChecked = thischeckBoxFrmChecked;
thisClose();
}
上面的代碼我們通過把textBoxFrm的Text和checkBoxFrmChecked賦給textBoxFrm和checkBoxFrm完成了對主窗體中的textBoxFrm和checkBoxFrm的修改因為textBoxFrm和textBoxFrm是同一個引用而checkBoxFrm和checkBoxFrm也是
到這裡為止功能是實現了但是總覺得不是很合理讓兩個窗體控件傳來傳去現在我舉一個恰當一點的例子
修改了兩個窗體
<第二個例子>
說明在這個例子中我們的兩個窗體都加了一個ListBox用來顯示ArrayList中的內容
主窗體中控件listBoxFrmbuttonEdit
子窗體中控件listBoxFrmtextBoxAddbuttonAddbuttonEditbuttonOK
這次我們用ArrayList來作為傳遞數據在Form中定義類數據成員
private ArrayList listData;
在構造函數中增加了對listData進行內存分配並生成數據最終綁定到listBoxFrm
public Form()
{
InitializeComponent();
thislistData = new ArrayList();
thislistDataAdd(DotNet);
thislistDataAdd(C#);
thislistDataAdd();
thislistDataAdd(WebService);
thislistDataAdd(XML);
thislistBoxFrmDataSource = thislistData;
}
另外對修改按鈕點擊事件處理函數的修改如下
private void buttonEdit_Click(object sender SystemEventArgs e)
{
Form formChild = new Form(thislistData);
formChildShowDialog();
thislistBoxFrmDataSource = null;
thislistBoxFrmDataSource = thislistData;
}
相對與主窗體對子窗體作相應修改也在Form中增加了類數據成員
private ArrayList listData;
用來保存對主窗體中listData的引用
修改構造函數
public Form(ArrayList listData)
{
InitializeComponent();
thislistData = listData;
foreach(object o in thislistData)
{
thislistBoxFrmItemsAdd(o);
}
}
這裡讓listData同listData指向同一個引用另外沒有對listBoxFrm進行綁定采用了填充
好了下面是對數據操作的時候了
添加處理函數代碼如下
private void buttonAdd_Click(object sender SystemEventArgs e)
{
if(thistextBoxAddTextTrim()Length>)
{
thislistDataAdd(thistextBoxAddTextTrim());
thislistBoxFrmItemsAdd(thistextBoxAddTextTrim());
}
else
MessageBoxShow(請輸入添加的內容!);
}
刪除處理代碼如下
private void buttonDel_Click(object sender SystemEventArgs e)
{
int index = thislistBoxFrmSelectedIndex;
if(index!=)
{
thislistDataRemoveAt(index);
thislistBoxFrmItemsRemoveAt(index);
}
else
MessageBoxShow(請選擇刪除項或者沒有可刪除的項!);
}
退出Form子窗體
private void buttonOK_Click(object sender SystemEventArgs e)
{
thisClose();
}
編譯運行程序在子窗體中對數據進行修改關閉後主窗體就會顯示更新後的數據
這裡有一點要提醒一下比較兩個例子我們都傳的是引用類型一個是String另一個是ArrayList為什麼string類型不能修改主窗體的數據呢?其實在Net中對string類型的修改並不是修改原來的值原來的值沒有變化而是重新生成一個新的字符串下面是一個很好的說明
public class ZZConsole
{
[STAThread]
static void Main(string[] args)
{
string str = abc;
string str = str;
str = ;
ConsoleWriteLine(str);
ConsoleWriteLine();
ConsoleWriteLine(str);
ConsoleWriteLine();
ArrayList al = new ArrayList();
alAdd(abc);
ArrayList al = al;
alAdd();
foreach(object o in al)
ConsoleWriteLine((string)o);
ConsoleWriteLine();
foreach(object o in al)
ConsoleWriteLine((string)o);
ConsoleReadLine();
}
}
運行一下看看輸出結果就明白了另外對值類型的數據操作要使用ref關鍵字
總結我們通過帶參數的構造函數實現了窗體間的數據交互代碼看上去也比較清楚在實際開發過程中可以把DataSetDataTable或者是DataView當作參數當然如果只是想修改一行可以傳個DataRow或者DataRowView在下面的文章中我們來看看怎樣使用另外兩種方法來實現數據的交互
From:http://tw.wingwit.com/Article/program/net/201311/12858.html