本節介紹的這種實現窗體間資料傳送的方法要比第一篇介紹的方法要難許多,其難點就在於如何修改建構函式。對於那些要從其他窗體中要訪問的資料,必須設定修改為"public",否則無法實現窗體間資料傳遞。
下面介紹另外一種從主窗體向從窗體傳遞資料的實現方法,這種方法能夠完全解決上面的二個缺點,程式在主窗體中就像操作窗體中加入的元件一樣,靈活的操作從窗體。
設計思路
此方法實現二個功能:
其一,主窗體能夠實時地向從窗體傳送資料,表現為當更改主窗體中的跟蹤條(TrackBar)的數值,從窗體中定義的一個Label元件就顯示出跟蹤條的當前數值;
其二,從窗體能夠向主窗體提出資料請求,並且能夠獲取主窗體中各元件顯示的資料。程式表現為,當單擊從窗體中的【從Form1中獲取資料】按鈕,程式能夠把主窗體中的二個TextBox元件顯示的內容傳遞到從窗體,並且通過從窗體中的二個TextBox元件分別顯示出來。
第一個功能的實現思路是把從窗體看成是主窗體的一個例項,加入到從窗體中的元件,可以看出是從窗體中定義的一個個變數,由於從窗體中加入的元件的元件預設定義型別是Private(私有的),所以要想訪問這些元件,必須改變為Public(共有的);而第二個功能的實現思路是通過修改Form2的建構函式,建構函式實現功能是通過Form1類的例項(即為主窗體)來建立並初始化Form2類的例項(即為從窗體)。這樣對於從窗體來說,主窗體則為其一個例項,從而也就可以向主窗體提出資料請求,當然要把需要訪問的各元件定義型別從預設的Private(私有的)型別修改為Public(共有的)。上述二個功能的實現方法,第二種方法比較複雜,希望各位能夠結合後面的具體實現程式碼來理解。
第二種窗體間的資料傳遞情況實現步驟
1.首先建立一個Visual
C#的專案檔案,專案名稱為【VC#中不同窗體資料傳遞方法02】。
2.把Visual
Studio
.Net的當前視窗切換到【Form1.cs(設計)】視窗,並從【工具箱】中的【Windows窗體】選項卡中拖入下列元件到【Form1.cs(設計)】窗體中,並執行相應操作:
·
二個TextBox元件,用以輸入向Form2窗體傳送的資料
·
二個Label元件
·
一個TrackBar元件,名稱為trackBar1。
3.把Visual
Studio
.Net的當前視窗切換到【Form1.cs】視窗,即:Form1.cs的程式碼編輯視窗。並用下列程式碼替換替代系統產生的InitializeComponent過程。
private
void InitializeComponent ( )
{
this.label1
= new System.Windows.Forms.Label ( ) ;
this.label2
= new System.Windows.Forms.Label ( ) ;
this.textBox1
= new System.Windows.Forms.TextBox ( ) ;
this.textBox2
= new System.Windows.Forms.TextBox ( ) ;
this.trackBar1
= new System.Windows.Forms.TrackBar ( ) ;
(
( System.ComponentModel.ISupportInitialize ) ( this.trackBar1 )
).BeginInit
( ) ;
this.SuspendLayout
( ) ;
this.label1.Location
= new System.Drawing.Point ( 27 , 41 ) ;
this.label1.Name
= "label1" ;
this.label1.TabIndex
= 0 ;
this.label1.Text
= "歡迎詞:" ;
this.label2.Location
= new System.Drawing.Point ( 27 , 83 ) ;
this.label2.Name
= "label2" ;
this.label2.TabIndex
= 1 ;
this.label2.Text
= "提示資訊:" ;
this.textBox1.Location
= new System.Drawing.Point ( 108 , 38 ) ;
this.textBox1.Name
= "textBox1" ;
this.textBox1.TabIndex
= 2 ;
this.textBox1.Text
= "" ;
this.textBox2.Location
= new System.Drawing.Point ( 109 , 78 ) ;
this.textBox2.Name
= "textBox2" ;
this.textBox2.TabIndex
= 3 ;
this.textBox2.Text
= "" ;
this.trackBar1.LargeChange
= 1 ;
this.trackBar1.Location
= new System.Drawing.Point ( 12 , 182 ) ;
this.trackBar1.Maximum
= 100 ;
this.trackBar1.Name
= "trackBar1" ;
this.trackBar1.Size
= new System.Drawing.Size ( 272 , 42 ) ;
this.trackBar1.TabIndex
= 1 ;
this.trackBar1.ValueChanged
+= new System.EventHandler (
this.trackBar1_ValueChanged
) ;
this.AutoScaleBaseSize
= new System.Drawing.Size ( 6 , 14 ) ;
this.ClientSize
= new System.Drawing.Size ( 292 , 273 ) ;
this.Controls.AddRange
( new System.Windows.Forms.Control[] {
this.trackBar1 ,
this.textBox2 ,
this.textBox1 ,
this.label2 ,
this.label1 } ) ;
this.MaximizeBox
= false ;
this.MinimizeBox
= false ;
this.Name
= "Form1" ;
this.Text
= "Form1" ;
this.Load
+= new System.EventHandler ( this.Form1_Load ) ;
(
( System.ComponentModel.ISupportInitialize ) ( this.trackBar1 )
).EndInit
( ) ;
this.ResumeLayout
( false ) ;
}
4.由於從窗體向主窗體提出的資料請求是二個TextBox元件的"Text"屬性值,所以要修改Form1.cs檔案中這二個TextBox元件的定義型別,把預設定義為"private"型別修改為"public"型別,修改後的這二個TextBox元件在Form1.cs中的定義語句如下:
public
System.Windows.Forms.TextBox textBox1 ;
public
System.Windows.Forms.TextBox textBox2 ;
在上述程式碼後面再新增下面程式碼,下面程式碼是建立一個Form2類的例項m_Form,即從窗體:
private
Form2 m_Form ;
5.在Form1.cs中的Main函式後,新增下列程式碼,下列程式碼的功能是實現當修改主窗體中的跟蹤條數值後,從窗體中的label3元件的顯示數值能夠隨之而變化,這樣就實現主窗體實時傳遞資料到從窗體了:
private
void trackBar1_ValueChanged ( object sender , System.EventArgs e )
{
m_Form.label3
.Text = trackBar1.Value.ToString ( ) ;
}
6.在新增完上面程式碼,並在其後部,再新增下列程式碼,下列程式碼的功能是使用Form2類的建構函式,並通過Form1類的例項來建立並初始化Form2類的例項。在專案檔案中加入Form2類,並修改Form2類的建構函式工作將在本節的第7到11步驟中完成。
private
void Form1_Load ( object sender , System.EventArgs e )
{
m_Form
= new Form2 ( this ) ;
//通過主窗體來建立、初始化從窗體
m_Form.Show
( ) ;
//顯示從窗體
}
7.選擇選單【專案】 【新增Windows窗體】後,彈出【新增新項-VC#中不同窗體資料傳遞方法01】對話方塊。在此對話方塊中的【名稱(N):】文字框中輸入【Form2】後,單擊【開啟】按鈕,則在VC#中不同窗體資料傳遞方法01專案中添加了一個新的窗體,名稱為【Form2】。
8.把Visual
Studio
.Net的當前視窗切換到【Form2.cs(設計)】視窗,並從【工具箱】中的【Windows窗體】選項卡中拖入下列元件到【Form2.cs(設計)】窗體中,並執行相應操作:
·
二個TextBox元件,用以顯示向主窗體請求獲得的資料。
·
二個Label元件。
·
一個Button元件,名稱為button1。
9.把Visual
Studio
.Net的當前視窗切換到【Form2.cs】視窗,即:Form2.cs的程式碼編輯視窗。並用下列程式碼替換替代系統產生的InitializeComponent過程。
{
this.textBox1
= new System.Windows.Forms.TextBox ( ) ;
this.textBox2
= new System.Windows.Forms.TextBox ( ) ;
this.label2
= new System.Windows.Forms.Label ( ) ;
this.label1
= new System.Windows.Forms.Label ( ) ;
this.button1
= new System.Windows.Forms.Button ( ) ;
this.label3
= new System.Windows.Forms.Label ( ) ;
this.SuspendLayout
( ) ;
this.textBox1.Location
= new System.Drawing.Point ( 95 , 42 ) ;
this.textBox1.Name
= "textBox1" ;
this.textBox1.Size
= new System.Drawing.Size ( 125 , 21 ) ;
this.textBox1.TabIndex
= 2 ;
this.textBox1.Text
= "" ;
this.textBox2.Location
= new System.Drawing.Point ( 94 , 80 ) ;
this.textBox2.Name
= "textBox2" ;
this.textBox2.Size
= new System.Drawing.Size ( 127 , 21 ) ;
this.textBox2.TabIndex
= 3 ;
this.textBox2.Text
= "" ;
this.label2.Location
= new System.Drawing.Point ( 27 , 83 ) ;
this.label2.Name
= "label2" ;
this.label2.TabIndex
= 5 ;
this.label2.Text
= "提示資訊:" ;
this.label1.Location
= new System.Drawing.Point ( 38 , 45 ) ;
this.label1.Name
= "label1" ;
this.label1.TabIndex
= 4 ;
this.label1.Text
= "歡迎詞:" ;
this.button1.Location
= new System.Drawing.Point ( 80 , 136 ) ;
this.button1.Name
= "button1" ;
this.button1.Size
= new System.Drawing.Size ( 135 , 53 ) ;
this.button1.TabIndex
= 6 ;
this.button1.Text
= "從Form1中獲取資料" ;
this.button1.Click
+= new System.EventHandler ( this.button1_Click ) ;
this.label3.Location
= new System.Drawing.Point ( 102 , 210 ) ;
this.label3.Name
= "label3" ;
this.label3.TabIndex
= 7 ;
this.AutoScaleBaseSize
= new System.Drawing.Size ( 6 , 14 ) ;
this.ClientSize
= new System.Drawing.Size ( 292 , 273 ) ;
this.Controls.AddRange
( new System.Windows.Forms.Control[] {
this.label3 ,
this.button1 ,
this.textBox2 ,
this.textBox1 ,
this.label2 ,
this.label1 } ) ;
this.MaximizeBox
= false ;
this.MinimizeBox
= false ;
this.Name
= "Form2" ;
this.Text
= "Form2" ;
this.ResumeLayout
( false ) ;
}
10.由於主窗體是把其中的跟蹤條的數值通過從窗體中的label元件來顯示的,所以必須把Form2.cs檔案中建立label3元件時定義的"private"型別修改為"public"型別,修改後的建立label3元件的程式碼為:
public
System.Windows.Forms.Label label3 ;
由於Form2類的例項是通過Form1類的例項來初始化,所以在建立label3元件後面新增下列程式碼,下列程式碼是建立一個Form1類的例項,其作用是初始化Form2類的例項(即從窗體):
private
Form1 mF_Form ;
11.修改Form2類的建構函式,具體操作如下,用下列程式碼替換Form2.cs中預設的建構函式:
public
Form2 ( Form1 myForm )
{
//
//
Windows 窗體設計器支援所必需的
//
InitializeComponent
( ) ;
this.mF_Form
= myForm ;
//
//
TODO: 在 InitializeComponent 呼叫後新增任何建構函式程式碼
//
}
12.在Form2.cs中的Main函式後,新增下列程式碼,下列程式碼的功能是實現向主窗體提出資料請求,並獲取主窗體的資料,當然這些資料的型別必須修改為"public"型別。
private
void button1_Click ( object sender , System.EventArgs e )
{
textBox1.Text
= this.mF_Form.textBox1.Text ;
textBox2.Text
= this.mF_Form.textBox2.Text ;
}
13.至此,在上述步驟都成功完成,並全部儲存後,Visual
C#實現窗體間傳遞資料第二種情況的處理方法就全部完成了。此時單擊快捷鍵【F5】就可以執行程式了,當調整Form1窗體的跟蹤條數值,我們會發現Form2窗體中的label3元件顯示的數值也隨之變化;當在Form1窗體的二個TextBox元件中輸入資料後,單擊Form2窗體中的【從Form2中獲取資料】按鈕,則程式能夠成功的從Form1中獲取資料,並通過Form2中對應的TextBox元件顯示出來。圖01就是程式執行後的介面:
在上一篇文章中我們曾經指出指出,窗體間資料傳遞第一種情況的解決方法存在一個主要的缺點,就是窗體間傳遞的引數數目是固定的,並且型別也是固定的。這是因為,上文中修改了從名稱空間System.Windows.Forms中的Form類派生而得到的Form2類的建構函式,由於建構函式中的引數和型別都是固定的,而主窗體向從窗體傳遞資料,就是通過建構函式中的引數來實現的,所以就造成了上面的那個缺點。其實在這種方法中還存在一個缺點,就是每一次窗體間的資料傳遞,就必須構建一個窗體,並且這種資料傳遞是一次性的。這些缺點對於窗體間傳遞少量資料,一般不會有太大影響,但如果要傳遞大量資料,並且要通過主窗體來實時向從窗體傳遞資料,使用這種方法就勉為其難了。