Visual C#中实现窗体间的数据传递之一 Visual C#中实现窗体间的数据传递之一 一个稍微复杂一点的程序一般都有二个或者更多的窗体。有时在程序设计中,数据不仅要在 同一个窗体中传递,还要在窗体间传递,这种传递是主窗体与从窗体之间数据的互相传递。 从本文开始,我们将列举不同窗体间数据传递的四种情况,和用Visual C#实现这四种情况的具体方法。下面先介绍用Visual C#实现窗体间传递数据中第一种情 况——从主窗体向从窗体传递字符串。在阅读完本文后,你还尝试一下利用此方法在窗体间 传送数值等数据。 本文中程序设计、调试、运行的软件环境: Windows2000 服务器版 Visual Studio.Net正式版,.Net FrameWork SDK版本号3705 实现步骤: 1.启动Visual Studio .Net 2.选择菜单【文件】|【新建】|【项目】后,弹出【新建项目】对话框 3.将【项目类型】设置为【Visual C#项目】 4.将【模板】设置为【控制台应用程序】 5.在【名称】文本框中输入【VC#中不同窗体数据传递方法01】 6.在【位置】的文本框中输入【E:/VS.NET项目】,然后单击【确定】按钮,这样VC#中不 同窗体数据传递方法01项目就创建完成了 7.把Visual Studio.Net的当前窗口切换到【Form1.cs(设计)】窗口,并从【工具箱】中 的【Windows窗体】选项卡中拖入下列组件到【Form1.cs(设计)】窗体中,并执行相应操 作: · 二个TextBox组件,用以输入向Form2窗体传送的数据 · 二个Label组件 · 一个Button组件,名称为button1,并在拖入【Form1.cs(设计)】窗体后,双击它,则 Visual Stuido .Net产生其Click事件对应的处理代码。 8.把Visual Studio .Net的当前窗口切换到【Form1.cs】窗口,即:Form1.cs的代码编辑窗 口。并用下列代码替换替代系统产生的InitializeComponent过程。 private void InitializeComponent ( ) { this.button1 = new System.Windows.Forms.Button ( ) ; this.textBox1 = new System.Windows.Forms.TextBox ( ) ; this.textBox2 = new System.Windows.Forms.TextBox ( ) ; this.label1 = new System.Windows.Forms.Label ( ) ; this.label2 = new System.Windows.Forms.Label ( ) ; this.SuspendLayout ( ) ; this.button1.Location = new System.Drawing.Point ( 103 , 149 ) ; this.button1.Name = "button1" ; this.button1.Size = new System.Drawing.Size ( 75 , 36 ) ; this.button1.TabIndex = 0 ; this.button1.Text = "发送" ; this.button1.Click += new System.EventHandler ( this.button1_Click ) ; this.textBox1.Location = new System.Drawing.Point ( 93 , 56 ) ; this.textBox1.Name = "textBox1" ; this.textBox1.Size = new System.Drawing.Size ( 122 , 21 ) ; this.textBox1.TabIndex = 1 ; this.textBox1.Text = "" ; this.textBox2.Location = new System.Drawing.Point ( 93 , 99 ) ; this.textBox2.Name = "textBox2" ; this.textBox2.Size = new System.Drawing.Size ( 123 , 21 ) ; this.textBox2.TabIndex = 2 ; this.textBox2.Text = "" ; this.label1.Location = new System.Drawing.Point ( 29 , 57 ) ; this.label1.Name = "label1" ; this.label1.TabIndex = 3 ; this.label1.Text = "欢迎词:" ; this.label2.Location = new System.Drawing.Point ( 16 , 100 ) ; this.label2.Name = "label2" ; this.label2.TabIndex = 4 ; this.label2.Text = "提示信息:" ; this.AutoScaleBaseSize = new System.Drawing.Size ( 6 , 14 ) ; this.ClientSize = new System.Drawing.Size ( 263 , 223 ) ; this.Controls.AddRange ( new System.Windows.Forms.Control[ ] { this.textBox2 , this.textBox1 , this.button1 , this.label2 , this.label1 } ) ; this.Name = "Form1" ; this.Text = "Form1" ; this.Load += new System.EventHandler ( this.Form1_Load ) ; this.ResumeLayout ( false ) ; } 此时,VC#中不同窗体数据传递方法01项目的主窗体Form1的设计界面就完成了,具体如图 1所示: 图1:VC#中不同窗体数据传递方法01项目主窗体设计界面 9.把Visual Studio.Net的当前窗口切换到Form1.cs的代码编辑窗口,并用下列代码替换For m1.cs中button1组件的Click事件对应的处理代码。 private void button1_Click ( object sender , System.EventArgs e ) { Form2 myForm = new Form2 ( textBox1.Text , textBox2.Text ) ; myForm.Show ( ) ; } 10.选择菜单【项目】|【添加Windows窗体】后,弹出【添加新项-VC#中不同窗体数据传 递方法01】对话框。在此对话框中的【名称(N):】文本框中输入【Form2】后,单击【打 开】按钮,则在VC#中不同窗体数据传递方法01项目中添加了一个新的窗体,名称为【Form 2】。 11.把Visual Studio.Net的当前窗口切换到【Form2.cs(设计)】窗口,并从【工具箱】中 的【Windows窗体】选项卡中拖入下列组件到【Form2.cs(设计)】窗体中,并执行相应操 作: · 二个TextBox组件,用以显示从Form1传送来的字符串数据 · 二个Label组件 · 一个Button组件,名称为button1,并在拖入【Form2.cs(设计)】窗体后,双击它,则 Visual Stuido .Net产生其Click事件对应的处理代码。 12.把Visual Studio.Net的当前窗口切换到Form2.cs的代码编辑窗口,并在定义Form2代码 的后部添加下列代码,下列代码是定义二个字符串变量,用以接收从Form1传送来的字符串 数据: private string str1 , str2 ; 13.并用下列代码替换系统产生的Form2对应的代码: public Form2 ( string sendData01 , string sendData02 ) { // // Windows 窗体设计器支持所必需的 // InitializeComponent ( ) ; str1 = sendData01 ; str2 = sendData02 ; // // TOD 在 InitializeComponent 调用后添加任何构造函数代码 // } 14.用下列代码替换Form2.cs中的由Visual Studio .Net系统产生的InitializeComponent过 程: private void InitializeComponent ( ) { this.textBox2 = new System.Windows.Forms.TextBox ( ) ; this.textBox1 = new System.Windows.Forms.TextBox ( ) ; this.button1 = new System.Windows.Forms.Button ( ) ; this.label2 = new System.Windows.Forms.Label ( ) ; this.label1 = new System.Windows.Forms.Label ( ) ; this.SuspendLayout ( ) ; this.textBox2.Location = new System.Drawing.Point ( 109 , 93 ) ; this.textBox2.Name = "textBox2" ; this.textBox2.Size = new System.Drawing.Size ( 123 , 21 ) ; this.textBox2.TabIndex = 7 ; this.textBox2.Text = "" ; this.textBox1.Location = new System.Drawing.Point ( 109 , 50 ) ; this.textBox1.Name = "textBox1" ; this.textBox1.Size = new System.Drawing.Size ( 122 , 21 ) ; this.textBox1.TabIndex = 6 ; this.textBox1.Text = "" ; this.button1.Location = new System.Drawing.Point ( 75 , 143 ) ; this.button1.Name = "button1" ; this.button1.Size = new System.Drawing.Size ( 119 , 43 ) ; this.button1.TabIndex = 5 ; this.button1.Text = "显示传送来数据" ; this.button1.Click += new System.EventHandler ( this.button1_Click ) ; this.label2.Location = new System.Drawing.Point ( 32 , 94 ) ; this.label2.Name = "label2" ; this.label2.TabIndex = 9 ; this.label2.Text = "提示信息:" ; this.label1.Location = new System.Drawing.Point ( 45 , 51 ) ; this.label1.Name = "label1" ; this.label1.TabIndex = 8 ; this.label1.Text = "欢迎词:" ; this.AutoScaleBaseSize = new System.Drawing.Size ( 6 , 14 ) ; this.ClientSize = new System.Drawing.Size ( 265 , 228 ) ; this.Controls.AddRange ( new System.Windows.Forms.Control[ ] { this.textBox2 , this.textBox1 , this.button1 , this.label2 , this.label1 } ) ; this.Name = "Form2" ; this.Text = "Form2" ; this.ResumeLayout ( false ) ; } 15.用下列代码替换Form2.cs中button1组件Click事件对应的处理代码,下列代码的作用是 把从Form1窗体中接收来的字符串数据通过同样的方式显示出来: private void button1_Click ( object sender , System.EventArgs e ) { textBox1.Text = str1 ; textBox2.Text = str2 ; } 16.至此,在上述步骤都正确完成,并全部保存后,VC#中不同窗体数据传递方法01项目的 全部工作就完成了。图02是VC#中不同窗体数据传递方法01程序的运行界面。其中Form2中 显示出来的字符串就是从主窗体中传递过去的。 图02:VC#中不同窗体数据传递方法01程序的运行界面 总结 用Visual C#实现窗体间数据传递的第一种情况的全部工作就完成了,细心的读者已经发现 ,这种方法明显存在一个主要缺点,就是主窗体向从窗体传递数据的数目是固定的。这个缺 点将在下一篇文章中彻底加以解决。 |
标 题: Visual C#中实现窗体间的数据传递之二
在上一篇文章中我们曾经指出指出,窗体间数据传递第一种情况的解决方法存在一个主要的
缺点,就是窗体间传递的参数数目是固定的,并且类型也是固定的。这是因为,上文中修改
了从命名空间System.Windows.Forms中的Form类派生而得到的Form2类的构造函数,由于构
造函数中的参数
和类型都是固定的,而主窗体向从窗体传递数据,就是通过构造函数中的参数来实现的,所
以就造成了上面的那个缺点。其实在这种方法中还存在一个缺点,就是每一次窗体间的数据
传递,就必须构建一个窗体,并且这种数据传递是一次性的。这些缺点对于窗体间传递少量
数据,一般不会
有太大影响,但如果要传递大量数据,并且要通过主窗体来实时向从窗体传递数据,使用这
种方法就勉为其难了。
下面介绍另外一种从主窗体向从窗体传递数据的实现方法,这种方法能够完全解决上面的二
个缺点,程序在主窗体中就像操作窗体中加入的组件一样,灵活的操作从窗体。
设计思路
此方法实现二个功能:
其一,主窗体能够实时地向从窗体传送数据,表现为当更改主窗体中的跟踪条(TrackBar)
的数值,从窗体中定义的一个Label组件就显示出跟踪条的当前数值;
其二,从窗体能够向主窗体提出数据请求,并且能够获取主窗体中各组件显示的数据。程序
表现为,当单击从窗体中的【从Form1中获取数据】按钮,程序能够把主窗体中的二个TextB
ox组件显示的内容传递到从窗体,并且通过从窗体中的二个TextBox组件分别显示出来。
第一个功能的实现思路是把从窗体看成是主窗体的一个实例,加入到从窗体中的组件,可以
看出是从窗体中定义的一个个变量,由于从窗体中加入的组件的组件缺省定义类型是Privat
e(私有的),所以要想访问这些组件,必须改变为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"属性值,所以要修改For
m1.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组件来显示的,所以必须把Fo
rm2.cs文件中创建label3组件时定义的"private"类型修改为"public"类型,修改后的创建l
abel3组件的代码为:
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 ;
//
// TOD 在 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就是程序运行后的界面:
图01:【VC#中不同窗体数据传递方法02】程序的运行界面
小结
本节介绍的这种实现窗体间数据传送的方法要比第一篇介绍的方法要难许多,其难点就在于
如何修改构造函数。对于那些要从其他窗体中要访问的数据,必须设定修改为"public",否
则无法实现窗体间数据传递。
这二篇文章介绍的都是主窗体向从窗体传递数据,在下一篇文章中,将介绍从窗体向主窗体
传递数据的实现方法。
标 题: Visual C#中实现窗体间的数据传递之三
前面的二篇文章中(Visual C#实现窗体间数据传递1,2),我们已经分别探讨了主窗体向
从窗体传递数据的二种实现方法,在接下来内容中,我们将介绍从从窗体向主窗体传递数据
的二种常用的处理方法。
在下面这种从从窗体向主窗体传递数据的方法中,将接触到C#中二个比较重要,也是比较
难以掌握的二个概念:委托(Delegate)和事件(Event)。C#中的委托类似于C和C++中
的函数指针,但我们也知道,在C#并不提倡使用指针,因为这将会是的程序不受托管,而
因此变得不安全。
而委托和指针的主要区别就是,它是完全面相对象的,并且是类型安全的,通过委托使可以
实现把方法引用封装在委托对象内。然后再将该委托对象传递给可调用所引用方法的代码。
在C#中事件是当对象发生某些的事情时,类向该类的客户提供通知的一种方法。在本节介
绍的这种传递数
据的方法中就是通过事件来实现的。在C#中事件和委托的渊源勃深,这是因为在申明事件
的之前,首先要声明该事件的委托类型。在委托类型中将定义要传递给事件的一组参数(由
于本节要传递的是一个字符串,所以本节定义的委托类型中的参数类型为字符串)。在定义
完委托类型后,
再根据委托类型申明事件本身,在申明事件的时候要使用到关键字"event"。这样在上述工
作完成后,就可以像使用类中的其他事件一样使用申明、调用事件了。
委托类型和事件其实在用Visual Studio .Net开发C#应用程序的时候,经常使用到,只不
过,Visual Stduio .Net集成开发环境接管了这些工作,所以我们并没有意识到,下面这一
句代码是Visual Studio .Net定义Button类的实例button1的Click事件:
this.button1.Click += new System.EventHandler ( this.button1_Click ) ;
其中"Click"就是申明的事件,而"EventHandler"就是委托类型。但是这些事件和委托类型
都已经在.Net FrameWork SDK中定义完毕,所以,我们只要调用就可以了,但在本节介绍的
从从窗体向主窗体传递数据中,这些都需要我们来定义。
本文中程序设计、调试、运行的软件环境:
(1).Windows 2000 Server版
(2).Visual Studio .Net正式版,.Net FrameWork SDK版本号3705
实现从从窗体向主窗体传递数据
首先要我们要明确,主窗体其实是Form1类的实例,而从窗体是Form2类的实例。实现从从窗
体向主窗体传递数据的方法的主要思路是:s首先在Form2类中定义一个委托类型SendMess,
这个委托类型中的参数类型为一个字符串类型(就是通过这个类型来传送字符串数据的,当
然如果你存在其
他类型的数据,可以通过修改这个参数类型来完成),然后根据这个委托类型在Form2类中
申明一个Send事件。这样当在Form1类中创建一个Form2类的实例的时候,同时也为这个Form
2类实例定义一个Send事件。当在从窗体中单击按钮时,则在按钮的单击事件中触发Send事
件,并以从窗体中
要传递的字符串作为参数,同时在主窗体中的处理Send事件的代码中,通过TextBox组件的t
ext属性来接收从窗体传递来的字符串数据,至此就实现了把从窗体中的字符串数据传递到
主窗体中了。虽然实现的功能不是很负责,但涉及到的知识却是很多的,也很让人胡涂!下
面是这种方法的
具体的实现步骤:
1.首先创建一个Visual C#的项目文件,项目名称为【VC#中不同窗体数据传递方法03】。
2.把Visual Studio .Net的当前窗口切换到【Form1.cs(设计)】窗口,并从【工具箱】中
的【Windows窗体】选项卡中拖入下列组件到【Form1.cs(设计)】窗体中,并执行相应操
作:
一个TextBox组件,用以显示从从窗体传递来的字符串数据。
一个Label组件。
一个Button组件,名称为button1,并在button1被拖入窗体后,双击,则系统产生其Click
事件对应的处理代码。
3.把Visual Studio .Net的当前窗口切换到【Form1.cs】窗口,即:Form1.cs的代码编辑窗
口。并用下列代码替换替代系统产生的InitializeComponent过程。
private void InitializeComponent ( )
{
this.textBox1 = new System.Windows.Forms.TextBox ( ) ;
this.label1 = new System.Windows.Forms.Label ( ) ;
this.button1 = new System.Windows.Forms.Button ( ) ;
this.SuspendLayout ( ) ;
this.textBox1.Location = new System.Drawing.Point ( 107 , 71 ) ;
this.textBox1.Name = "textBox1" ;
this.textBox1.Size = new System.Drawing.Size ( 140 , 21 ) ;
this.textBox1.TabIndex = 0 ;
this.textBox1.Text = "" ;
this.label1.Location = new System.Drawing.Point ( 17 , 78 ) ;
this.label1.Name = "label1" ;
this.label1.TabIndex = 1 ;
this.label1.Text = "传递来的数据:" ;
this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat ;
this.button1.Location = new System.Drawing.Point ( 104 , 143 ) ;
this.button1.Name = "button1" ;
this.button1.Size = new System.Drawing.Size ( 91 , 41 ) ;
this.button1.TabIndex = 2 ;
this.button1.Text = "显示Form2" ;
this.button1.Click += new System.EventHandler ( this.button1_Click ) ;
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.button1 ,
this.textBox1 ,
this.label1 } ) ;
this.MaximizeBox = false ;
this.MinimizeBox = false ;
this.Name = "Form1" ;
this.Text = "从窗体向主窗体传递数据" ;
this.ResumeLayout ( false ) ;
myForm.Send += new Form2.SendMess ( Send ) ;
}
请注意上述代码中粗体的代码,上述代码是定义Form2类实例myForm的Send事件,其中"Send
Mess"是定义的委托类型。定义"SendMess"和"Send"代码位于项目文件中的Form2.cs中。
4.在Form1.cs中的class的代码区加入下列代码,下列代码是创建一个Form2类的实例,并初
始化:
private Form2 myForm = new Form2 ( ) ;
5.在Form1.cs中的Main函数之后,加入下列代码,下列代码的功能是处理myForm中的Send事
件,正是在Send事件中实现从从窗体向主窗体传递字符串数据:
private void Send ( string str )
{
textBox1.Text = str ;
//把接收来的字符串通过TextBox组件显示出来
}
6.用下列代码替换Form1.cs中button1组件的Click事件对应的处理代码,下列代码的作用是
显示Form2类的实例myForm:
private void button1_Click ( object sender , System.EventArgs e )
{
myForm.ShowDialog ( ) ;
//显示从窗体
}
7.选择菜单【项目】|【添加Windows窗体】后,弹出【添加新项-VC#中不同窗体数据传递
方法03】对话框。在此对话框中的【名称(N):】文本框中输入【Form2】后,单击【打开
】按钮,则在VC#中不同窗体数据传递方法03项目中添加了一个新的窗体,名称为【Form2】
。
8.把Visual Studio .Net的当前窗口切换到【Form2.cs(设计)】窗口,并从【工具箱】中
的【Windows窗体】选项卡中拖入下列组件到【Form2.cs(设计)】窗体中,并执行相应操
作:
一个TextBox组件,用以输入向主窗体传递的字符串数据。
一个Label组件。
一个Button组件,名称为button1,并在button1被拖入窗体后,双击之,则系统产生其Clic
k事件对应的处理代码。
9.把Visual Studio .Net的当前窗口切换到【Form2.cs】窗口,即:Form2.cs的代码编辑窗
口。并用下列代码替换替代系统产生的InitializeComponent过程。
private void InitializeComponent ( )
{
this.label1 = new System.Windows.Forms.Label ( ) ;
this.textBox1 = new System.Windows.Forms.TextBox ( ) ;
this.button1 = new System.Windows.Forms.Button ( ) ;
this.SuspendLayout ( ) ;
this.label1.Location = new System.Drawing.Point ( 30 , 62 ) ;
this.label1.Name = "label1" ;
this.label1.Size = new System.Drawing.Size ( 163 , 23 ) ;
this.label1.TabIndex = 0 ;
this.label1.Text = "传递到主窗体的字符串:" ;
this.textBox1.Location = new System.Drawing.Point ( 37 , 94 ) ;
this.textBox1.Name = "textBox1" ;
this.textBox1.Size = new System.Drawing.Size ( 187 , 21 ) ;
this.textBox1.TabIndex = 1 ;
this.textBox1.Text = "" ;
this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat ;
this.button1.Location = new System.Drawing.Point ( 99 , 155 ) ;
this.button1.Name = "button1" ;
this.button1.Size = new System.Drawing.Size ( 85 , 41 ) ;
this.button1.TabIndex = 2 ;
this.button1.Text = "传递" ;
this.button1.Click += new System.EventHandler ( this.button1_Click ) ;
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.button1 ,
this.textBox1 ,
this.label1 } ) ;
this.MaximizeBox = false ;
this.MinimizeBox = false ;
this.Name = "Form2" ;
this.Text = "Form2" ;
this.ResumeLayout ( false ) ;
}
10.在Form2.cs的class代码区添加下列代码,下列代码是在Form2类中增加一个事件类型Sen
d,当然首先要定义一个委托类型SendMess:
public delegate void SendMess ( string str ) ;
//定义委托类型
public event SendMess Send ;
//定义一个事件类型
11.用下列代码替换Form2.cs中button2的Click事件对应的处理代码,下列代码的功能是触
发Send事件,传递字符串数据:
public void button2_Click ( object sender , System.EventArgs e )
{
Send(TextBox1.Text);
}
12.至此,在上述步骤都正确完成,并成功保存后,【VC#中不同窗体数据传递方法03】项
目的全部工作就完成了。此时单击快捷键【F5】运行程序,单击主窗体中【显示Form2】按
钮,则从窗体Form2就显示出来,在Form2中的【传递到主窗体的字符串】文本框中输入"Hel
lo
World!"后,单击【传递】按钮,则程序就能够把字符串"Hello World!"传递到主窗体,并
通过主窗体中的【传递来的字符串】文本框显示出来,图01是【VC#中不同窗体数据传递方
法03】程序的运行界面:
总结
本节介绍的虽然是从从窗体向主窗体传递字符串类型数据。对于其他类型的数据(如:Imag
e类型)其实现的方法也是一样的,只不过在定义委托类型时,其参数类型要定义为Image类
型。同时在程序的其他对应地方做相应的修改就可以了,希望诸位能够亲自尝试一下,这对
了解、掌握Dele
gate、Event在C#中的用法是非常有帮助。对于Visual C#初学者来说,本文介绍的这种方
法是难以理解的,但本文介绍的这种方法对于精通Visual C#编程是很有帮助的,对理解Vi
sual C#编程思想也有很大的益处,因为我们最常用的C#的开发工具Visual Studio
.Net,由于其功能实在太强大,并且操作方便,在编程中替代我们做了许多烦杂的工作,这
些替代工作的确给我们编程带来了许多方便、加快了编程速度,但同时也掩盖了许多相对底
层的操作,使得我们对某些操作并不觉察,就是觉察到,也很难理解其中的来龙去脉缺。而
本文就简单的介
绍了一些功能实现方式,所以希望读者在通读完本文后,不仅能够掌握从窗体向主窗体传递
数据的方法,也能够加深对这些关键理解和掌握程度。
楼主的三种方法,我都有实现过,不过感觉:
第一种方法,也就是两个窗体是聚合关系,如果需求允许,我认为是不错的方法,实现其来比较轻量级,如果想传递多参数,可以使用params [] object,或者NameValueCollection呀
第二种方法,从设计上是最不可取的,两个类耦合太紧,互相保留对方的引用,很不提倡。而且,有些应该是private的地方改成了public,破坏了封装性。
第三种方法,如果对event理解够深的话,还是很好的,主要是可以利用.NET的event,可以实时的通知主窗体,而且不用保留主窗体的引用,同时子窗体对主窗体的存在已无所知,这样设计相对合理一些。
但是,如果从逻辑上父、子窗体就属于一个层次,或者交互部十分频繁,没有想到其他的消息通知机制的话,那也就只好采用第二种方法,作为没办法的办法。。。。
要在窗体之间传递数据应该还有两种方法。
其一,用一个类封装一些静态变量,供两窗体使用。
其二,还可以把数据保存到应用程序域(AppDomain)中。
具体何时用哪种方法由需求定。