| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 10045 人关注过本帖, 3 人收藏
标题:[原创]两个窗体之间传递数据
取消只看楼主 加入收藏
月夜枫华
Rank: 4
等 级:贵宾
威 望:12
帖 子:437
专家分:42
注 册:2006-1-2
收藏(3)
 问题点数:0 回复次数:8 
[原创]两个窗体之间传递数据

来论坛这么久了,在C#版也"混"了一年多,除了在提问时发起过帖子以外从来没说过什么技术性问题.
既然是第一次我就一定要把自己的话说出来,我从来都是使用自己的方法,可能不是最好的,但一定是解决问题的.
如果有比我更好的方法,请不要吝啬,我有哪里说错的,请指正!
下面说正题:
如题,我们经常需要在两个窗体间传递数据,我从前都是使用类的静态变量来进行传递.后来群里有人说我这是"严重违反了OOP思想",确实是这样,而且这个方法在多线程的程序中很不适用.
目前我们使用的比较多情况就是在某个新窗体出现时,需要传递一些参数,这里我通常是重载新窗体的构造函数
比如:
原构造函数:
public Form2()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
我们将这个方法复制粘贴一份以后修改新的构造方法,参数可以随意指定
public Form2(string parameter1,int parameter2)
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
我们在调用时(假设主窗体是Form1)直接使用:Form2 form2=new Form2(str1,str2);
这样就可以把两个参数传递到Form2中了.如果是在多线程中,需要两个窗体同时操作的,还可以考虑使用公有变量,但要注意保护锁的问题.
再说说如果Form2中产生了一些数据,如何传递给Form1.
目前我认为比较好的方式是使用自定义事件.
首先,我们根据需要回传的数据定义一个事件数据提供类型,在这里我假设要回传两个数据,一个是整型(int),一个是字符串(string)那么定义下边的类.注意:这个类一定要从System.EventArgs继承
public class ReturnEventArgs:System.EventArgs
{
  public string strMsg;
public int intMsg;
public ReturnEventArgs()//编写构造函数,可以使用参数的形式直接构造字段或属性
{}
}
我们在Form2里定义1个代理:
public delegate void ReturnDataEventHandler(object sender,ReturnEventArgs e);
再定义一个事件
public event ReturnDataEventHandler ReturnMsg;
在窗体中再添加一个按钮,在按钮的单击事件里写下:
public void button1_click(object sender,System.EventArgs e)
{
ReturnEventArgs rea=new ReturnEventArgs();
rea.strMsg="字符串参数";
rea.intMsg=100;
if(ReturnMsg!=null)//加此判断的作用是为了在此事件未实现的时候不会出现错误
{
ReturnMsg(this,rea);
}
}
在Form1里生成Form2的时候:
Form2 frm=new Form2();
frm.ReturnMsg+=Form2.ReturnMsg(frm_ReturnMsg);
并直接生成事件处理函数
public void frm_RetrunMsg(object sender,ReturnEventArgs e)
{
//这里就可以直接使用事件数据类e所包含的数据
string str=e.strMsg;
int i=e.intMsg;
}

以上的方法可能在很多书中介绍了,也可能有很多人已经会了,但这可是偶无师自通的.
如果大家有更好的方法请告诉我,谢谢大家
这里的语句都是偶在论坛里手动写的,可能有错误,不过我这里讲的是方法不是代码,如有错误请大家见谅!

搜索更多相关主题的帖子: 窗体 数据 
2006-02-26 22:44
月夜枫华
Rank: 4
等 级:贵宾
威 望:12
帖 子:437
专家分:42
注 册:2006-1-2
收藏
得分:0 
最近手头的项目比较多,过几天闲下来做个例子给大家看下.

2006-03-06 22:44
月夜枫华
Rank: 4
等 级:贵宾
威 望:12
帖 子:437
专家分:42
注 册:2006-1-2
收藏
得分:0 
keikei
你的错误应该是命名空间没有引入好吧,系统没有找到ReturnEventArgs所在的命名空间.

2006-05-20 10:07
月夜枫华
Rank: 4
等 级:贵宾
威 望:12
帖 子:437
专家分:42
注 册:2006-1-2
收藏
得分:0 

我今天准备下,明天贴出示例代码.
还有就是21楼的兄弟,你用的方法只适合引用类型,如果是值类型就不好使了.


2006-05-22 12:29
月夜枫华
Rank: 4
等 级:贵宾
威 望:12
帖 子:437
专家分:42
注 册:2006-1-2
收藏
得分:0 
真的很对不起,手上工作太多了,没有按照约定准时上传,在此深表歉意!
这次我上传的项目功能不大,只是为了阐明我之前所说的观点,如果还有疑问欢迎继续跟贴.

2006-05-27 09:50
月夜枫华
Rank: 4
等 级:贵宾
威 望:12
帖 子:437
专家分:42
注 册:2006-1-2
收藏
得分:0 

怎么没上传上来呢,那就把代码贴上来吧.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace TransData
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.NumericUpDown numericUpDown1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;

public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}

/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(40, 56);
this.label1.Name = "label1";
this.label1.TabIndex = 0;
this.label1.Text = "数据参数";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// label2
//
this.label2.Location = new System.Drawing.Point(40, 88);
this.label2.Name = "label2";
this.label2.TabIndex = 1;
this.label2.Text = "字符参数";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// numericUpDown1
//
this.numericUpDown1.Location = new System.Drawing.Point(152, 56);
this.numericUpDown1.Name = "numericUpDown1";
this.numericUpDown1.TabIndex = 2;
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(152, 88);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(120, 21);
this.textBox1.TabIndex = 3;
this.textBox1.Text = "";
//
// button1
//
this.button1.Location = new System.Drawing.Point(88, 160);
this.button1.Name = "button1";
this.button1.TabIndex = 4;
this.button1.Text = "打开新窗口";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(336, 309);
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.numericUpDown1);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

private void button1_Click(object sender, System.EventArgs e)
{
Form2 frm=new Form2((int)this.numericUpDown1.Value,this.textBox1.Text);//使用已经重载的窗体构造函数
frm.OnTranData+=new TranDataEventHandler(frm_OnTranData);//使用事件
frm.Show();
}

private void frm_OnTranData(object sender, TranDataEventArgs e)
{
//在事件处理函数中使用回传的数据
this.numericUpDown1.Value=e.IntData;
this.textBox1.Text=e.StrData;
}
}
}


2006-05-27 09:55
月夜枫华
Rank: 4
等 级:贵宾
威 望:12
帖 子:437
专家分:42
注 册:2006-1-2
收藏
得分:0 

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace TransData
{
/// <summary>
/// Form2 的摘要说明。
/// </summary>
public class Form2 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.NumericUpDown numericUpDown1;
public event TranDataEventHandler OnTranData;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;

public Form2()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
public Form2(int Pam1,string Pam2)//重载的构造函数为Form1-->Form2传数据做准备
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
this.numericUpDown1.Value=Pam1;
this.textBox2.Text=Pam2;

//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}

/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.textBox2 = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(120, 200);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "回传";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// textBox2
//
this.textBox2.Location = new System.Drawing.Point(160, 128);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(120, 21);
this.textBox2.TabIndex = 2;
this.textBox2.Text = "";
//
// label1
//
this.label1.Location = new System.Drawing.Point(40, 64);
this.label1.Name = "label1";
this.label1.TabIndex = 3;
this.label1.Text = "数字参数";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// label2
//
this.label2.Location = new System.Drawing.Point(40, 128);
this.label2.Name = "label2";
this.label2.TabIndex = 4;
this.label2.Text = "字符参数";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// numericUpDown1
//
this.numericUpDown1.Location = new System.Drawing.Point(160, 64);
this.numericUpDown1.Name = "numericUpDown1";
this.numericUpDown1.TabIndex = 5;
this.numericUpDown1.Value = new System.Decimal(new int[] {
10,
0,
0,
0});
//
// Form2
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(336, 317);
this.Controls.Add(this.numericUpDown1);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.textBox2);
this.Controls.Add(this.button1);
this.Name = "Form2";
this.Text = "Form2";
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
this.ResumeLayout(false);

}
#endregion

private void button1_Click(object sender, System.EventArgs e)
{
TranDataEventArgs ea=new TranDataEventArgs((int)this.numericUpDown1.Value,this.textBox2.Text);//生成事件所携带的数据
if(OnTranData!=null)//进行一次判断,防止窗体1不使用事件时出现异常
{
OnTranData(this,ea);//使用事件
}
}
}
public delegate void TranDataEventHandler(object sender,TranDataEventArgs e);//事件处理函数委托
public class TranDataEventArgs:System.EventArgs//包含事件代理所需要的数据,必须从此类继承
{
int iData;
string sData;
public TranDataEventArgs(int Pam1,string Pam2)
{
this.iData=Pam1;
this.sData=Pam2;
}
public int IntData
{
get
{
return this.iData;
}
}
public string StrData
{
get
{
return this.sData;
}
}
}
}


2006-05-27 09:55
月夜枫华
Rank: 4
等 级:贵宾
威 望:12
帖 子:437
专家分:42
注 册:2006-1-2
收藏
得分:0 
numericUpDown1是控件,只允许输入数字的.VS2003自带的.

2006-05-28 18:16
月夜枫华
Rank: 4
等 级:贵宾
威 望:12
帖 子:437
专家分:42
注 册:2006-1-2
收藏
得分:0 
public class TranDataEventArgs:System.EventArgs//包含事件代理所需要的数据,必须从此类继承
{
int iData;
string sData;
public TranDataEventArgs(int Pam1,string Pam2)
{
this.iData=Pam1;
this.sData=Pam2;
}
public int IntData
{
get
{
return this.iData;
}
}
public string StrData
{
get
{
return this.sData;
}
}
}
是在窗体2的代码页里定义的,只要跟主程序在同一个命名空间下就没问题.因为这个类是自定义的,如果不和主程序在同一个命名空间下或者引用它的程序没有带着完全限定的命名空间,就会出现你说的错误.

2006-05-31 21:17
快速回复:[原创]两个窗体之间传递数据
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019666 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved