創建一個Winform窗體應用程序項目,然后添加一個Form2窗體。
在Form1和Form2中各添加一個textBox和button:
單擊Form1中的button1,彈出Form2,然后要做的就是在Form1中的textBox1和Form2中的textBox2中傳值。
為了方便起見,將Form1稱作父窗體,將Form2稱作子窗體。
相對來說,將父窗體的值傳到子窗體較為容易實現。下面分別進行說明。
一、父窗體傳值給子窗體。
方法1:通過Form類構造方法的重載傳參。
Form1類中代碼:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form1 : Form 7 { 8 public Form1() 9 { 10 InitializeComponent(); 11 } 12 13 private void button1_Click(object sender, EventArgs e) 14 { 15 Form2 f2 = new Form2(textBox1.Text); 16 f2.ShowDialog(); 17 } 18 } 19 }
Form2類中代碼:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form2 : Form 7 { 8 public Form2() 9 { 10 InitializeComponent(); 11 } 12 13 public Form2(string str) 14 { 15 InitializeComponent(); 16 textBox2.Text = str;//這句必須放在InitializeComponent();的后面,否則會引起“空引用異常” 17 } 18 19 } 20 }
方法2:通過外部可訪問的中間變量傳參。
先看一串無法實現目的的代碼。
Form1中:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form1 : Form 7 { 8 public Form1() 9 { 10 InitializeComponent(); 11 } 12 13 public string str;//public類型的實例字段 14 15 private void button1_Click(object sender, EventArgs e) 16 { 17 Form2 f2 = new Form2(); 18 str = textBox1.Text;//注意,這句不能放在f2.ShowDialog();的后面,否則會先執行textBox2.Text = f1.str;再執行str = textBox1.Text; 19 f2.ShowDialog(); 20 } 21 } 22 }
Form2中:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form2 : Form 7 { 8 public Form2() 9 { 10 InitializeComponent(); 11 } 12 13 private void Form2_Load(object sender, EventArgs e) 14 { 15 Form1 f1 = new Form1(); 16 textBox2.Text = f1.str; 17 } 18 19 } 20 }
結果值沒有傳過來:
這是因為:Form1 f1 = new Form1();相當於新建了一個對象,這個新對象的str初始值是null(只有該對象的button1被click的時候才會改變str的值)。textBox2.Text = f1.str;其實就是將null賦給了textBox2.Text。
調試如圖:
static變量可以認為是全局變量,static變量被所有對象所共有,也可以被所有對象所改變,將相關代碼修改如下即可:
public static string str;//public類型的實例字段 private void Form2_Load(object sender, EventArgs e) { textBox2.Text = Form1.str; }
它有一種變式:
Form1中:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form1 : Form 7 { 8 public Form1() 9 { 10 InitializeComponent(); 11 } 12 13 private void button1_Click(object sender, EventArgs e) 14 { 15 Form2 f2 = new Form2(); 16 f2.str = textBox1.Text; 17 f2.ShowDialog(); 18 19 } 20 } 21 }
Form2中:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form2 : Form 7 { 8 public Form2() 9 { 10 InitializeComponent(); 11 } 12 13 public string str;//這里str是在Form2類中定義的,並且不需要static關鍵字 14 15 private void Form2_Load(object sender, EventArgs e) 16 { 17 textBox2.Text = str; 18 } 19 20 } 21 }
分析: f2.str = textBox1.Text;將textBox1的值賦給f2.str,由於f2.ShowDialog();跳出來的剛好是這個對象,因此這個對象的str值不為空。最終通過textBox2.Text = str;將值傳過去了。跟上一個例子的不同之處是:str聲明的位置不一樣,一個是在Form1類中,一個是在Form2類中。
一、子窗體傳值給父窗體。
方法1:通過Owner設置窗口歸屬來傳值。
① 通過Controls
Form1中:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form1 : Form 7 { 8 public Form1() 9 { 10 InitializeComponent(); 11 } 12 13 private void button1_Click(object sender, EventArgs e) 14 { 15 Form2 f2 = new Form2(); 16 f2.ShowDialog(this);//這個this必不可少(將窗體顯示為具有指定所有者:窗體f2的所有者是Form1類當前的對象) 17 } 18 } 19 }
Form2中:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form2 : Form 7 { 8 public Form2() 9 { 10 InitializeComponent(); 11 } 12 13 private void button2_Click(object sender, EventArgs e) 14 { 15 Form1 f1 = (Form1) this.Owner;//將本窗體的擁有者強制設為Form1類的實例f1 16 f1.Controls["textBox1"].Text = textBox2.Text; 17 } 18 19 } 20 }
② 通過在控件所在類中增加改變控件屬性的方法
或者通過在Form1中添加一個ChangeText方法也行:
public void ChangeText(string str) { textBox1.Text = str; }
Form2中代碼相應改變為:
private void button2_Click(object sender, EventArgs e) { Form1 f1 = (Form1) this.Owner;//將本窗體的擁有者強制設為Form1類的實例f1 f1.ChangeText(textBox2.Text); }
注意:如果不用Owner,僅僅想用下面的代碼實現,是沒可能的。
//Form1中: using System; using System.Windows.Forms; namespace WindowsForms跨窗體傳值大全 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Form2 f2 = new Form2(); f2.ShowDialog(); } public void ChangeText(string str) { textBox1.Text = str; } } } //Form2中: using System; using System.Windows.Forms; namespace WindowsForms跨窗體傳值大全 { public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void button2_Click(object sender, EventArgs e) { Form1 f1 =new Form1(); f1.ChangeText(textBox2.Text); } } } //這種代碼無法實現目的
③ 通過將外界不可訪問的控件“屬性”封裝成可以訪問的屬性。
Form1中:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form1 : Form 7 { 8 public Form1() 9 { 10 InitializeComponent(); 11 } 12 13 private void button1_Click(object sender, EventArgs e) 14 { 15 Form2 f2 = new Form2(); 16 f2.ShowDialog(this); 17 } 18 19 public string TextBox1Value 20 { 21 set { textBox1.Text = value; } 22 get { return textBox1.Text; } 23 } 24 25 } 26 }
Form2中:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form2 : Form 7 { 8 public Form2() 9 { 10 InitializeComponent(); 11 } 12 13 private void button2_Click(object sender, EventArgs e) 14 { 15 Form1 f1 =(Form1)this.Owner; 16 f1.TextBox1Value = textBox2.Text; 17 } 18 19 } 20 }
方法2:通過提供外部可訪問的屬性和DialogResult的狀態來傳值(這個例子同時實現了父傳子、子傳父)。
Form1中:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form1 : Form 7 { 8 public Form1() 9 { 10 InitializeComponent(); 11 } 12 13 private void button1_Click(object sender, EventArgs e) 14 { 15 Form2 f2 = new Form2(); 16 f2.TextBox2Value = textBox1.Text;//順便把父窗體的值先傳給子窗體 17 18 //這一行不需要再寫f2.ShowDialog();或者f2.Show();,否則f2會彈出來兩次 19 20 if (f2.ShowDialog() == DialogResult.OK)//這樣的語句是合法的:DialogResult f = f2.ShowDialog(); 21 { 22 textBox1.Text = f2.TextBox2Value; 23 //f2.Close();//這一句寫或者不寫,f2都會關閉 24 } 25 } 26 } 27 }
Form2中:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form2 : Form 7 { 8 public Form2() 9 { 10 InitializeComponent(); 11 } 12 13 public string TextBox2Value //將外部不可訪問的textBox2.Text封裝成屬性TextBox1Value 14 { 15 set { textBox2.Text = value; } 16 get { return textBox2.Text; } 17 } 18 19 private void button2_Click(object sender, EventArgs e) 20 { 21 this.DialogResult = DialogResult.OK;//這里的DialogResult是Form2類對象的屬性 22 } 23 24 } 25 }
方法3:通過委托事件來傳值。(這種方式可以實現不同控件數據實時聯動的復雜功能)
Form1中:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public partial class Form1 : Form 7 { 8 public Form1() 9 { 10 InitializeComponent(); 11 } 12 13 private void button1_Click(object sender, EventArgs e) 14 { 15 Form2 f2 = new Form2(); 16 f2.ChangeText += new ChangeTextHandler(Change_Text);//將事件和處理方法綁在一起,這句話必須放在f2.ShowDialog();前面 17 f2.ShowDialog(); 18 } 19 20 public void Change_Text(string str) 21 { 22 textBox1.Text = str; 23 } 24 } 25 }
Form2中:
1 using System; 2 using System.Windows.Forms; 3 4 namespace WindowsForms跨窗體傳值大全 5 { 6 public delegate void ChangeTextHandler(string str); //定義委托 7 8 public partial class Form2 : Form 9 { 10 public Form2() 11 { 12 InitializeComponent(); 13 } 14 15 public event ChangeTextHandler ChangeText; //定義事件 16 17 private void button2_Click(object sender, EventArgs e) 18 { 19 if (ChangeText != null)//判斷事件是否為空 20 { 21 ChangeText(textBox2.Text);//執行委托實例 22 this.Close(); 23 } 24 } 25 } 26 }
可以用.NET提供的Action<>泛型委托和lambda表達式簡化上面這個例子:
1 //Form1中: 2 using System; 3 using System.Windows.Forms; 4 5 namespace WindowsForms跨窗體傳值大全 6 { 7 public partial class Form1 : Form 8 { 9 public Form1() 10 { 11 InitializeComponent(); 12 } 13 14 private void button1_Click(object sender, EventArgs e) 15 { 16 Form2 f2 = new Form2(); 17 f2.ChangeText = (str) => textBox1.Text = str;//用lambda表達式實現,這句話必須放在f2.ShowDialog();前面 18 f2.ShowDialog(); 19 } 20 } 21 } 22 23 24 //Form2中: 25 using System; 26 using System.Windows.Forms; 27 28 namespace WindowsForms跨窗體傳值大全 29 { 30 public partial class Form2 : Form 31 { 32 public Form2() 33 { 34 InitializeComponent(); 35 } 36 37 public Action<string> ChangeText;//之前的定義委托和定義事件由這一句話代替 38 39 private void button2_Click(object sender, EventArgs e) 40 { 41 if (ChangeText != null)//判斷事件是否為空 42 { 43 ChangeText(textBox2.Text);//執行委托實例 44 this.Close(); 45 } 46 } 47 } 48 }
參考資料:
http://blog.csdn.net/yuekunge/article/details/9171301
http://www.jb51.net/article/63837.htm
http://jingyan.baidu.com/article/84b4f565d03bf360f6da3213.html