1. 程式人生 > >C#-MDI-多窗口通信方法總結

C#-MDI-多窗口通信方法總結

什麽 sys ... 界面 rac 數值 別人 thread tail

總結C#中窗體間傳遞數據的幾種方法 (由別人的方法整理)

轉自:http://blog.csdn.net/daisy423xu/article/details/1579854

在編寫C#windows應用程序的時候我們經常會遇到這種問題,怎麽樣在兩個窗體間傳遞數據呢?以下是我整理的網上的各種方法,在遇到一個實際問題:在form1中打開一個form2窗口作為錄入界面,將錄入的值經轉換後在form1中顯示。 采用了委托的方法,可以實現。(與VC的回調的應用相似)

1.可以通過委托的方法來解決

問題:通過form1做一個錄入界面,將裏邊通過文本框錄入的數值復值給 form2中的listview各列,用3個textbox1.text舉例吧,分別對應listview的3個列。

可以這麽做,如果兩個窗體是在同一個命名空間下

定義一個代理,註意這個代理是全局的:(即同一命名空間下,與Form1,Form2平級的)

public delegate void MyInvoke(string Item1,string Item2,string Item3);

//在窗體From2中有這麽一個回調函數,用於在ListView裏添加一個新項的:

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);

}

//比如說點擊Form2的一個按鈕彈出Form1進行錄入,在點擊按鈕的事件下:

//把委托傳過去

Form1 frmEdit=new Form1(new MyInvoke(UpdateListView));

frmEdit.ShowDialog(this);

//在Form1裏定義一個屬性

private MyInvoke mi=null;

在構造函數中接收這個委托:

public Form1(MyInvoke myInvoke)

{

this.mi=myInvoke;

}

//錄入數據後,點擊OK按鈕,在點擊事件下:

//回調

this.mi(this.TextBox1.Text,this.TextBox3.Text,this.TextBox3.Text);

this.Close();//關閉Form1

補充:如果我要是想再把form2的值給form1,

Form1 frmEdit=new Form1(new MyInvoke(UpdateListView),string para1,string para2...);

frmEdit.ShowDialog(this);

然後將Form1的構造函數改成可以接收幾個參數的就行了。

2.假如主框架為Form1,打開的搜索對話框是Form2.直接在Form2類中申明一個Form1實例:Form1 f1=new Form1();然後就可以通過f1來調用Form1中的域和函數了。其實不是這樣的,你申明的新的Form1實例不是原來的那個Form1對象了,這樣操作的是新的Form1中的域和函數,和最先打開的Form1是沒有關系的。

我們要做的是把當前的Form1實例傳遞給Form2,如果是這樣的話,問題就很好解決了。

方法1:首先,我們在Form2中定義:

private Form1 mF_Form

我們更改Form2的構造函數為有參數的

public Form2 ( Form1 myForm )
{
//
// Windows 窗體設計器支持所必需的
//
InitializeComponent ( ) ;
this.mF_Form = myForm ; /////這樣在Form1中申明Form2的時候就把Form1的實例傳遞過來了
//
// TODO: 在 InitializeComponent 調用後添加任何構造函數代碼
//
}

在Form1中,我在 要用到Form2的地方申明如下:

Form2 f2=new Form2(this);////這裏的this指的就是Form1當前的實例,也就是把當前Form1的實例通過Form2的構造函數傳遞給Form2類(其實在網上看到過比較蠢的方式,就是在構造函數裏面傳遞要傳遞的信息如:字符串或是數字等,這樣做很有局限性,不能傳遞其他的,所有我們可以直接傳遞實例,來完成傳遞更多的信息。)

這樣在Form2中使用myForm 就可以對原來的Form1窗口進行操作了。但是你要把要操作的Form1中的域和函數定義成public形式的(這樣可能不安全),此時的myForm就是真正的最開始打開的Form1了,你可以用這個實例來進行兩個窗體的通訊了。 ()

3.其實C#中提供了窗體間進行通訊的現成的屬性,呵呵,我們能想到的,微軟也想到了,他們創造的語言其實確實可以說是人性化了。

在Form1類中申明Form2時用如下代碼:

Form2 f2=new Form2();//////類Form2中的構造函數不改,還是無參的

f2.owner=this;////這裏的this指的是類Form1當前的實例。

//也可以使用函數的方法,給當前實例添加一個附屬窗口 代碼:this.AddOwnedForm(f2);

在Form2類的定義中寫如下代碼:

Form1 f1=this.owner;

這樣f1對應的就是原來的Form1的實例了,也就可以用這個進行通訊了。但是還是要把不同類之間訪問的域和函數定義成public,哎,安全確實是一個問題!!

4.使用靜態類
這個也是我們經常要用到的一種數據交互方法。

下面是定義的一個類:

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;

}

}

}

上面包含了一個靜態類成員,listData,一個靜態構造函數static AppDatas(),用來初始化listData的數據。還有一個靜態屬性ListData和一個靜態GetListData()方法,他們實現了同樣的功能就是返回listData。

由於前面兩篇文章已經講了很多,這裏不細說了,下面是完整的代碼:

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("請輸入添加的內容!");

}

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("請選擇刪除項!");

}

}

}

總結,我認為使用靜態類比較多的地方就是把應用程序的配置文件裝載到一個靜態類裏面,讓所有的窗體和其他實例都可以通過靜態屬性以及靜態方法使用這些數據,比如三層結構或多層結構都可以訪問它,而不是在多個實例間傳來傳去。在這裏我們討論的是Windows窗體,其實在兩個不同的實例間交互數據,都可以采用三篇文章中的方案實現,除非是這個類特有的屬性或著方法。現在都講完了,雖然不是什麽高深的東西,但是希望能對一些初學者有所幫助,同時也歡迎各位朋友進行技術交流,共同提高。

分析上面幾種方法:

1. 采用了委托的方法,可以實現。:很好的實現了數據處理與數據顯示的分離,即FORM2(主)顯示與FORM1數據處理,(不需要將FORM2的顯示放在FORM1中)與VC的回調的應用有延續性。並且確保了FORM1中要修改的屬性的私有性。

2. 方法2、3都是傳遞主窗口的引用,比較簡單易用。可以實現FORM2(主)與FORM1所有數據的傳遞(不過需要將要FORM1傳遞和要修改的數據設為PUBLIC),而這樣會存在安全問題。

委托方法可以很好地實現數據的保護

總結C#中窗體間傳遞數據的幾種方法 (由別人的方法整理)

在編寫C#windows應用程序的時候我們經常會遇到這種問題,怎麽樣在兩個窗體間傳遞數據呢?以下是我整理的網上的各種方法,在遇到一個實際問題:在form1中打開一個form2窗口作為錄入界面,將錄入的值經轉換後在form1中顯示。 采用了委托的方法,可以實現。(與VC的回調的應用相似)

1.可以通過委托的方法來解決

問題:通過form1做一個錄入界面,將裏邊通過文本框錄入的數值復值給 form2中的listview各列,用3個textbox1.text舉例吧,分別對應listview的3個列。

可以這麽做,如果兩個窗體是在同一個命名空間下

定義一個代理,註意這個代理是全局的:(即同一命名空間下,與Form1,Form2平級的)

public delegate void MyInvoke(string Item1,string Item2,string Item3);

//在窗體From2中有這麽一個回調函數,用於在ListView裏添加一個新項的:

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);

}

//比如說點擊Form2的一個按鈕彈出Form1進行錄入,在點擊按鈕的事件下:

//把委托傳過去

Form1 frmEdit=new Form1(new MyInvoke(UpdateListView));

frmEdit.ShowDialog(this);

//在Form1裏定義一個屬性

private MyInvoke mi=null;

在構造函數中接收這個委托:

public Form1(MyInvoke myInvoke)

{

this.mi=myInvoke;

}

//錄入數據後,點擊OK按鈕,在點擊事件下:

//回調

this.mi(this.TextBox1.Text,this.TextBox3.Text,this.TextBox3.Text);

this.Close();//關閉Form1

補充:如果我要是想再把form2的值給form1,

Form1 frmEdit=new Form1(new MyInvoke(UpdateListView),string para1,string para2...);

frmEdit.ShowDialog(this);

然後將Form1的構造函數改成可以接收幾個參數的就行了。

2.假如主框架為Form1,打開的搜索對話框是Form2.直接在Form2類中申明一個Form1實例:Form1 f1=new Form1();然後就可以通過f1來調用Form1中的域和函數了。其實不是這樣的,你申明的新的Form1實例不是原來的那個Form1對象了,這樣操作的是新的Form1中的域和函數,和最先打開的Form1是沒有關系的。

我們要做的是把當前的Form1實例傳遞給Form2,如果是這樣的話,問題就很好解決了。

方法1:首先,我們在Form2中定義:

private Form1 mF_Form

我們更改Form2的構造函數為有參數的

public Form2 ( Form1 myForm )
{
//
// Windows 窗體設計器支持所必需的
//
InitializeComponent ( ) ;
this.mF_Form = myForm ; /////這樣在Form1中申明Form2的時候就把Form1的實例傳遞過來了
//
// TODO: 在 InitializeComponent 調用後添加任何構造函數代碼
//
}

在Form1中,我在 要用到Form2的地方申明如下:

Form2 f2=new Form2(this);////這裏的this指的就是Form1當前的實例,也就是把當前Form1的實例通過Form2的構造函數傳遞給Form2類(其實在網上看到過比較蠢的方式,就是在構造函數裏面傳遞要傳遞的信息如:字符串或是數字等,這樣做很有局限性,不能傳遞其他的,所有我們可以直接傳遞實例,來完成傳遞更多的信息。)

這樣在Form2中使用myForm 就可以對原來的Form1窗口進行操作了。但是你要把要操作的Form1中的域和函數定義成public形式的(這樣可能不安全),此時的myForm就是真正的最開始打開的Form1了,你可以用這個實例來進行兩個窗體的通訊了。 ()

3.其實C#中提供了窗體間進行通訊的現成的屬性,呵呵,我們能想到的,微軟也想到了,他們創造的語言其實確實可以說是人性化了。

在Form1類中申明Form2時用如下代碼:

Form2 f2=new Form2();//////類Form2中的構造函數不改,還是無參的

f2.owner=this;////這裏的this指的是類Form1當前的實例。

//也可以使用函數的方法,給當前實例添加一個附屬窗口 代碼:this.AddOwnedForm(f2);

在Form2類的定義中寫如下代碼:

Form1 f1=this.owner;

這樣f1對應的就是原來的Form1的實例了,也就可以用這個進行通訊了。但是還是要把不同類之間訪問的域和函數定義成public,哎,安全確實是一個問題!!

4.使用靜態類
這個也是我們經常要用到的一種數據交互方法。

下面是定義的一個類:

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;

}

}

}

上面包含了一個靜態類成員,listData,一個靜態構造函數static AppDatas(),用來初始化listData的數據。還有一個靜態屬性ListData和一個靜態GetListData()方法,他們實現了同樣的功能就是返回listData。

由於前面兩篇文章已經講了很多,這裏不細說了,下面是完整的代碼:

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("請輸入添加的內容!");

}

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("請選擇刪除項!");

}

}

}

總結,我認為使用靜態類比較多的地方就是把應用程序的配置文件裝載到一個靜態類裏面,讓所有的窗體和其他實例都可以通過靜態屬性以及靜態方法使用這些數據,比如三層結構或多層結構都可以訪問它,而不是在多個實例間傳來傳去。在這裏我們討論的是Windows窗體,其實在兩個不同的實例間交互數據,都可以采用三篇文章中的方案實現,除非是這個類特有的屬性或著方法。現在都講完了,雖然不是什麽高深的東西,但是希望能對一些初學者有所幫助,同時也歡迎各位朋友進行技術交流,共同提高。

分析上面幾種方法:

1. 采用了委托的方法,可以實現。:很好的實現了數據處理與數據顯示的分離,即FORM2(主)顯示與FORM1數據處理,(不需要將FORM2的顯示放在FORM1中)與VC的回調的應用有延續性。並且確保了FORM1中要修改的屬性的私有性。

2. 方法2、3都是傳遞主窗口的引用,比較簡單易用。可以實現FORM2(主)與FORM1所有數據的傳遞(不過需要將要FORM1傳遞和要修改的數據設為PUBLIC),而這樣會存在安全問題。

委托方法可以很好地實現數據的保護

C#-MDI-多窗口通信方法總結