总结C#中窗体间传递数据的几种方法
?
在編寫(xiě)C#windows應(yīng)用程序的時(shí)候我們經(jīng)常會(huì)遇到這種問(wèn)題,怎么樣在兩個(gè)窗體間傳遞數(shù)據(jù)呢?以下是我整理的網(wǎng)上的各種方法,在遇到一個(gè)實(shí)際問(wèn)題:在form1中打開(kāi)一個(gè)form2窗口作為錄入界面,將錄入的值經(jīng)轉(zhuǎn)換后在form1中顯示。 采用了委托的方法,可以實(shí)現(xiàn)。(與VC的回調(diào)的應(yīng)用相似)
1.可以通過(guò)委托的方法來(lái)解決
問(wèn)題:通過(guò)form1做一個(gè)錄入界面,將里邊通過(guò)文本框錄入的數(shù)值復(fù)值給 form2中的listview各列,用3個(gè)textbox1.text舉例吧,分別對(duì)應(yīng)listview的3個(gè)列。
可以這么做,如果兩個(gè)窗體是在同一個(gè)命名空間下
定義一個(gè)代理,注意這個(gè)代理是全局的:(即同一命名空間下,與Form1,Form2平級(jí)的)
public delegate void MyInvoke(string Item1,string Item2,string Item3);
//在窗體From2中有這么一個(gè)回調(diào)函數(shù),用于在ListView里添加一個(gè)新項(xiàng)的:
private void UpdateListView(string Item1,string Item2,string Item3)
{
??? ListView1.Items.Add(Item1);
??? ListView1.Items[ListView1.Items.Count - 1].SubItems.Add(Item2);
??? ListView1.Items[ListView1.Items.Count - 1].SubItems.Add(Item3);
}
//比如說(shuō)點(diǎn)擊Form2的一個(gè)按鈕彈出Form1進(jìn)行錄入,在點(diǎn)擊按鈕的事件下:
//把委托傳過(guò)去
Form1 frmEdit=new Form1(new MyInvoke(UpdateListView));
frmEdit.ShowDialog(this);
//在Form1里定義一個(gè)屬性
private MyInvoke mi=null;
在構(gòu)造函數(shù)中接收這個(gè)委托:
public Form1(MyInvoke myInvoke)
{
?? this.mi=myInvoke;
}
//錄入數(shù)據(jù)后,點(diǎn)擊OK按鈕,在點(diǎn)擊事件下:
//回調(diào)
this.mi(this.TextBox1.Text,this.TextBox3.Text,this.TextBox3.Text);
this.Close();//關(guān)閉Form1
補(bǔ)充:如果我要是想再把form2的值給form1,
Form1 frmEdit=new Form1(new MyInvoke(UpdateListView),string para1,string para2...);
frmEdit.ShowDialog(this);
然后將Form1的構(gòu)造函數(shù)改成可以接收幾個(gè)參數(shù)的就行了
2.假如主框架為Form1,打開(kāi)的搜索對(duì)話框是Form2.直接在Form2類中申明一個(gè)Form1實(shí)例:Form1 f1=new Form1();然后就可以通過(guò)f1來(lái)調(diào)用Form1中的域和函數(shù)了。其實(shí)不是這樣的,你申明的新的Form1實(shí)例不是原來(lái)的那個(gè)Form1對(duì)象了,這樣操作的是新的Form1中的域和函數(shù),和最先打開(kāi)的Form1是沒(méi)有關(guān)系的。
我們要做的是把當(dāng)前的Form1實(shí)例傳遞給Form2,如果是這樣的話,問(wèn)題就很好解決了。
方法1:首先,我們?cè)贔orm2中定義:
private Form1 mF_Form
我們更改Form2的構(gòu)造函數(shù)為有參數(shù)的
public Form2 ( Form1 myForm )
{
// Windows 窗體設(shè)計(jì)器支持所必需的
InitializeComponent ( ) ;
this.mF_Form? = myForm ;?? /這樣在Form1中申明Form2的時(shí)候就把Form1的實(shí)例傳遞過(guò)來(lái)了
// TODO: 在 InitializeComponent 調(diào)用后添加任何構(gòu)造函數(shù)代碼
}
在Form1中,我在 要用到Form2的地方申明如下:
Form2 f2=new? Form2(this);這里的this指的就是Form1當(dāng)前的實(shí)例,也就是把當(dāng)前Form1的實(shí)例通過(guò)Form2的構(gòu)造函數(shù)傳遞給Form2類(其實(shí)在網(wǎng)上看到過(guò)比較蠢的方式,就是在構(gòu)造函數(shù)里面?zhèn)鬟f要傳遞的信息如:字符串或是數(shù)字等,這樣做很有局限性,不能傳遞其他的,所有我們可以直接傳遞實(shí)例,來(lái)完成傳遞更多的信息。)
這樣在Form2中使用myForm 就可以對(duì)原來(lái)的Form1窗口進(jìn)行操作了。但是你要把要操作的Form1中的域和函數(shù)定義成public形式的(這樣可能不安全),此時(shí)的myForm就是真正的最開(kāi)始打開(kāi)的Form1了,你可以用這個(gè)實(shí)例來(lái)進(jìn)行兩個(gè)窗體的通訊了。 ()
3.其實(shí)C#中提供了窗體間進(jìn)行通訊的現(xiàn)成的屬性,呵呵,我們能想到的,微軟也想到了,他們創(chuàng)造的語(yǔ)言其實(shí)確實(shí)可以說(shuō)是人性化了。
在Form1類中申明Form2時(shí)用如下代碼:
Form2 f2=new Form2();//類Form2中的構(gòu)造函數(shù)不改,還是無(wú)參的
f2.owner=this;這里的this指的是類Form1當(dāng)前的實(shí)例。
//也可以使用函數(shù)的方法,給當(dāng)前實(shí)例添加一個(gè)附屬窗口? 代碼:this.AddOwnedForm(f2);
在Form2類的定義中寫(xiě)如下代碼:
Form1 f1=this.owner;
這樣f1對(duì)應(yīng)的就是原來(lái)的Form1的實(shí)例了,也就可以用這個(gè)進(jìn)行通訊了。但是還是要把不同類之間訪問(wèn)的域和函數(shù)定義成public,哎,安全確實(shí)是一個(gè)問(wèn)題!!
?
? 4.使用靜態(tài)類
??? 這個(gè)也是我們經(jīng)常要用到的一種數(shù)據(jù)交互方法。
下面是定義的一個(gè)類:
using System;
using System.Collections;
namespace ZZ
{
???? public class AppDatas
???? {
???????? private static ArrayList listData;
???????? static AppDatas()
???????? {
????????????? listData = new ArrayList();
????????????? listData.Add("DotNet");
????????????? listData.Add("C#");
????????????? listData.Add("Asp.net");
????????????? listData.Add("WebService");
????????????? listData.Add("XML");
???????? }
???????? public static ArrayList ListData
???????? {
????????????? get{return listData;}
???????? }
???????? public static ArrayList GetListData()
???????? {
????????????? return listData;
???????? }
???? }
}
上面包含了一個(gè)靜態(tài)類成員,listData,一個(gè)靜態(tài)構(gòu)造函數(shù)static AppDatas(),用來(lái)初始化listData的數(shù)據(jù)。還有一個(gè)靜態(tài)屬性ListData和一個(gè)靜態(tài)GetListData()方法,他們實(shí)現(xiàn)了同樣的功能就是返回listData。
由于前面兩篇文章已經(jīng)講了很多,這里不細(xì)說(shuō)了,下面是完整的代碼:
Form1.cs文件
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace ZZ
{
???? public class Form1 : System.Windows.Forms.Form
???? {
???????? private System.Windows.Forms.Button buttonEdit;
???????? private System.Windows.Forms.ListBox listBoxFrm1;
???????? private System.ComponentModel.Container components = null;
???????? public Form1()
???????? {
????????????? InitializeComponent();
????????????? this.listBoxFrm1.DataSource = AppDatas.ListData;
???????? }
???????? protected override void Dispose( bool disposing )
???????? {
????????????? if( disposing )
?????????????????? if(components != null)
?????????????????????? components.Dispose();
????????????? base.Dispose( disposing );
???????? }
???????? [STAThread]
???????? static void Main()
???????? {
????????????? Application.Run(new Form1());
???????? }
???????? private void InitializeComponent()
???????? {
????????????? this.buttonEdit = new System.Windows.Forms.Button();
????????????? this.listBoxFrm1 = new System.Windows.Forms.ListBox();
????????????? this.SuspendLayout();
????????????? this.buttonEdit.Location = new System.Drawing.Point(128, 108);
????????????? this.buttonEdit.Name = "buttonEdit";
????????????? this.buttonEdit.TabIndex = 1;
????????????? this.buttonEdit.Text = "修改";
????????????? this.buttonEdit.Click += new System.EventHandler(this.buttonEdit_Click);
????????????? this.listBoxFrm1.ItemHeight = 12;
????????????? this.listBoxFrm1.Location = new System.Drawing.Point(12, 8);
????????????? this.listBoxFrm1.Name = "listBoxFrm1";
????????????? this.listBoxFrm1.Size = new System.Drawing.Size(108, 124);
????????????? this.listBoxFrm1.TabIndex = 2;
????????????? this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
????????????? this.ClientSize = new System.Drawing.Size(208, 141);
????????????? this.Controls.Add(this.listBoxFrm1);
????????????? this.Controls.Add(this.buttonEdit);
????????????? this.Name = "Form1";
????????????? this.Text = "Form1";
????????????? this.ResumeLayout(false);
???????? }
???????? private void buttonEdit_Click(object sender, System.EventArgs e)
???????? {
????????????? Form2 formChild = new Form2();
????????????? formChild.ShowDialog();
????????????? this.listBoxFrm1.DataSource = null;
????????????? this.listBoxFrm1.DataSource = AppDatas.ListData;
???????? }
???? }
}
?
Form2.cs文件
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace ZZ
{
???? public class Form2 : System.Windows.Forms.Form
???? {
???????? private System.Windows.Forms.Button buttonOK;
???????? private System.ComponentModel.Container components = null;
???????? private System.Windows.Forms.ListBox listBoxFrm2;
???????? private System.Windows.Forms.Button buttonAdd;
???????? private System.Windows.Forms.Button buttonDel;
???????? private System.Windows.Forms.TextBox textBoxAdd;
???????? public Form2()
???????? {
????????????? InitializeComponent();
????????????? foreach(object o in AppDatas.ListData)
?????????????????? this.listBoxFrm2.Items.Add(o);
???????? }
???????? protected override void Dispose( bool disposing )
???????? {
????????????? if( disposing )
?????????????????? if(components != null)
?????????????????????? components.Dispose();
????????????? base.Dispose( disposing );
???????? }
???????? private void InitializeComponent()
???????? {
????????????? this.buttonOK = new System.Windows.Forms.Button();
????????????? this.listBoxFrm2 = new System.Windows.Forms.ListBox();
????????????? this.buttonAdd = new System.Windows.Forms.Button();
????????????? this.buttonDel = new System.Windows.Forms.Button();
????????????? this.textBoxAdd = new System.Windows.Forms.TextBox();
????????????? this.SuspendLayout();
????????????? this.buttonOK.Location = new System.Drawing.Point(188, 108);
????????????? this.buttonOK.Name = "buttonOK";
????????????? this.buttonOK.TabIndex = 0;
????????????? this.buttonOK.Text = "確定";
????????????? this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);
????????????? this.listBoxFrm2.ItemHeight = 12;
????????????? this.listBoxFrm2.Location = new System.Drawing.Point(8, 8);
????????????? this.listBoxFrm2.Name = "listBoxFrm2";
????????????? this.listBoxFrm2.Size = new System.Drawing.Size(168, 124);
????????????? this.listBoxFrm2.TabIndex = 2;
????????????? this.buttonAdd.Location = new System.Drawing.Point(188, 44);
????????????? this.buttonAdd.Name = "buttonAdd";
????????????? this.buttonAdd.TabIndex = 3;
????????????? this.buttonAdd.Text = "增加";
????????????? this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click);
????????????? this.buttonDel.Location = new System.Drawing.Point(188, 76);
????????????? this.buttonDel.Name = "buttonDel";
????????????? this.buttonDel.TabIndex = 4;
????????????? this.buttonDel.Text = "刪除";
????????????? this.buttonDel.Click += new System.EventHandler(this.buttonDel_Click);
????????????? this.textBoxAdd.Location = new System.Drawing.Point(188, 12);
????????????? this.textBoxAdd.Name = "textBoxAdd";
????????????? this.textBoxAdd.Size = new System.Drawing.Size(76, 21);
????????????? this.textBoxAdd.TabIndex = 5;
????????????? this.textBoxAdd.Text = "";
????????????? this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
????????????? this.ClientSize = new System.Drawing.Size(272, 141);
????????????? this.Controls.Add(this.textBoxAdd);
????????????? this.Controls.Add(this.buttonDel);
????????????? this.Controls.Add(this.buttonAdd);
????????????? this.Controls.Add(this.listBoxFrm2);
????????????? this.Controls.Add(this.buttonOK);
????????????? this.Name = "Form2";
????????????? this.Text = "Form2";
????????????? this.ResumeLayout(false);
???????? }
???????? private void buttonOK_Click(object sender, System.EventArgs e)
???????? {
????????????? this.Close();
???????? }
???????? private void buttonAdd_Click(object sender, System.EventArgs e)
???????? {
????????????? if(this.textBoxAdd.Text.Trim().Length>0)
????????????? {
?????????????????? AppDatas.ListData.Add(this.textBoxAdd.Text.Trim());
?????????????????? this.listBoxFrm2.Items.Add(this.textBoxAdd.Text.Trim());
????????????? }
????????????? else
?????????????????? MessageBox.Show("請(qǐng)輸入添加的內(nèi)容!");???
???????? }
???????? private void buttonDel_Click(object sender, System.EventArgs e)
???????? {
????????????? int index = this.listBoxFrm2.SelectedIndex;
????????????? if(index!=-1)
????????????? {
??????????????????? AppDatas.ListData.RemoveAt(index);
?????????????????? this.listBoxFrm2.Items.RemoveAt(index);
????????????? }
????????????? else
?????????????????? MessageBox.Show("請(qǐng)選擇刪除項(xiàng)!");
???????? }
???? }
}???
???? 總結(jié),我認(rèn)為使用靜態(tài)類比較多的地方就是把應(yīng)用程序的配置文件裝載到一個(gè)靜態(tài)類里面,讓所有的窗體和其他實(shí)例都可以通過(guò)靜態(tài)屬性以及靜態(tài)方法使用這些數(shù)據(jù),比如三層結(jié)構(gòu)或多層結(jié)構(gòu)都可以訪問(wèn)它,而不是在多個(gè)實(shí)例間傳來(lái)傳去。在這里我們討論的是Windows窗體,其實(shí)在兩個(gè)不同的實(shí)例間交互數(shù)據(jù),都可以采用三篇文章中的方案實(shí)現(xiàn),除非是這個(gè)類特有的屬性或著方法。現(xiàn)在都講完了,雖然不是什么高深的東西,但是希望能對(duì)一些初學(xué)者有所幫助,同時(shí)也歡迎各位朋友進(jìn)行技術(shù)交流,共同提高。
分析上面幾種方法:
1.? 采用了委托的方法,可以實(shí)現(xiàn)。:很好的實(shí)現(xiàn)了數(shù)據(jù)處理與數(shù)據(jù)顯示的分離,即FORM2(主)顯示與FORM1數(shù)據(jù)處理,(不需要將FORM2的顯示放在FORM1中)與VC的回調(diào)的應(yīng)用有延續(xù)性。并且確保了FORM1中要修改的屬性的私有性。
2.? 方法2、3都是傳遞主窗口的引用,比較簡(jiǎn)單易用。可以實(shí)現(xiàn)FORM2(主)與FORM1所有數(shù)據(jù)的傳遞(不過(guò)需要將要FORM1傳遞和要修改的數(shù)據(jù)設(shè)為PUBLIC),而這樣會(huì)存在安全問(wèn)題。
委托方法可以很好地實(shí)現(xiàn)數(shù)據(jù)的保護(hù)
轉(zhuǎn)載于:https://www.cnblogs.com/wsxg/archive/2012/04/05/2433491.html
總結(jié)
以上是生活随笔為你收集整理的总结C#中窗体间传递数据的几种方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 程序员需要谨记的9个安全编码规则【转载】
- 下一篇: GridView绑定时通过RowData