C#跨窗體傳值的幾種方法分析(很詳細)


創建一個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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM