winForm两个Form窗口之间的传值
- 格式:doc
- 大小:28.50 KB
- 文档页数:5
C#Winform窗⼝之间传值的多种⽅法浅析(转)摘要这篇⽂章主要介绍了C# Winform窗⼝之间传值的多种⽅法浅析,本⽂起讲解了通过构造器传值、通过属性传递、通过事件携带参数传递等⽅法,需要的朋友可以参考下⼀般的⼯程都是多个form组成的,各个窗体之间经常要灵活的传递数据。
下⾯分享⼀点⾃⼰的经验:窗体传值的⽅法有很多,下⾯仅介绍我⽤过的⼀些,不知道官⽅叫这些什么⽅法,⼤家也可以找找看其他的。
通过构造器传值这是最简单的⼀种⽅式,例如我从form1中要传⼀个字符串去form2⾸先,在form2的构造器中稍作修改:复制代码代码如下:public Form2(String s){InitializeComponent();belRecieve.Text = s;}添加了⼀个string参数 s然后,在form1的click事件中,将要传递的参数传⼊,如下⽚断:复制代码代码如下:private void buttonShow_Click(object sender, EventArgs e){…Form2 f2;if (textBoxSend.Text == ""){f2 = new Form2("I'm from form1");}else{f2 = new Form2(textBoxSend.Text);}DialogResult r = f2.ShowDialog();//⾄于Show与ShowDialog就不⽤再说了吧…}在触发click事件的时候,form2就接受到f1传过去的textBoxSend.Text或者"I'm from form1",并且⽤labelRecieve去承接它。
这种⽅法,虽然简单⽅便,但是毕竟功能有限,当需要传递较⼤量的多样的数据时,⽤构造器就不能胜任了。
通过属性传递属性可以⽅便的传递多个数据(不就是添加多个属性么?),假设我要从form2传递某字符串到form3,⾸先我们为form3添加⼀个属性叫myString复制代码代码如下:public Form3(){InitializeComponent();}public string myString{get{return this.textBoxf3.Text;}set{if (value == null)textBoxf3.Text = string.Empty;elsetextBoxf3.Text = value;}}通过该属性去设置⽂本框的text.然后,在form2的点击事件中,只需令复制代码代码如下:f3.myString = "I'm from form2";这样也很⽅便,值得⼀提的是,这样通过属性传递的时候,即可以将数据从form2船到form3⼜可以从form3传回来。
窗体之间传递值的⼏种⽅法窗体之间传递值的⼏种⽅法场景如下:我有⼀个mainFrm(⽗窗体),⼀个subFrm(⼦窗体)点击⽗窗体的按钮启动⼦窗体,点击⼦窗体的按钮可以给⽗窗体设置值。
如下图第⼀种⽅法:启动⼦窗体,将整个窗体(this)传递过去。
(不建议使⽤)步骤如下:1.在主窗体写⼀个函数SetText函数(这个地⽅也就是嵌⼊代码,你需要改那个窗体的内容,就在那个窗体写⼀个修改的函数。
public void SetText(string msg) //这个地⽅SetText是公有的{this.textBox1.Text = msg;}2.在new ⼦窗体的时候加⼊参数this.private void button1_Click(object sender, EventArgs e){subFrm frm = new subFrm(this); //这个⽅法的核⼼就是传递thisfrm.Show();}3.给⼦窗体添加构造函数重载(⼦窗体持有⼀个mainFrm类的变量parentFrm)。
public subFrm(mainFrm parentFrm):this(){this._parentFrm = parentFrm;}4.在⼦窗体的button事件上添加如下代码:private void button1_Click(object sender, EventArgs e){string sendText = this.textBox1.Text;this._parentFrm.SetText(sendText);}第⼆种:使⽤委托步骤如下:1.在主窗体写⼀个函数SetText函数(这个地⽅也就是嵌⼊代码,你需要改那个窗体的内容,就在那个窗体写⼀个修改的函数。
private void SetText(string msg){this.textBox1.Text = msg;}2.在⼦窗体⾥⾯定义⼀个委托(算是委托类吧), public delegate void SendMsgDelegate(string msg); 这个定义要和主函数的SetText⽅法⼀致(返回值是void,参数是string) 并且在定义⼀个委托(算是委托变量吧) public SendMsgDelegate sendMsg;⽤委托定义⼀个委托变量,这个委托变量只能接受返回值是void,参数是string的函数)。
WinForm窗口之间传递参数的几种方法。
(下面做了一个小示例,因其浅显易懂,就不加注释了。
若有疑问可给我发邮件@)using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WinPassValue{publicpartialclass MainForm : Form{public MainForm(){InitializeComponent();SelectedType();}publicdelegatevoid ChangeFormValue(string s1);//开始传递privatevoid btnPass_Click(object sender, EventArgs e) {if (cbmSelectedType.SelectedIndex == 3){Form3 f3 = new Form3(txtValue);f3.Show();}elseif (cbmSelectedType.SelectedIndex == 2){Form2 f2 = new Form2(txtValue.Text);f2.Show();}elseif (cbmSelectedType.SelectedIndex == 1){Program.yourName = txtValue.Text;Form1 f1 = new Form1();f1.Show();}//利用Show方法重载实现。
注意,此时要设置要传递控件访问权限为public 或 internalelseif (cbmSelectedType.SelectedIndex == 5){Form5 f5 = new Form5();f5.Show(this);}//委托事件传值elseif (cbmSelectedType.SelectedIndex == 4) {Form4 f4 = new Form4();//订阅事件f4.MyEvent +=new Form4.PassValue(myPassValue);f4.Show();}}//定义方法publicstring myPassValue(){return txtValue.Text.Trim();}//定义方法用于选择传递参数的方式privatevoid SelectedType(){string[] strValue = { "-请选择要传递的方式-","全局变量传递","构造函数传值","控件传值","委托事件传值","Show方法重载!"};cbmSelectedType.Items.AddRange(strValue); cbmSelectedType.SelectedIndex = 0;}privatevoid MainForm_Load(object sender, EventArgs e){}}}using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WinPassValue{publicpartialclass Form1 : Form{public Form1(){InitializeComponent();}privatevoid Form1_Load(object sender, EventArgs e){textBox1.ReadOnly = true;textBox1.Text = Program.yourName+"采用全局变量的方式实现!";}}}using System;using System.Collections.Generic; using ponentModel; using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WinPassValue{publicpartialclass Form2 : Form{public Form2(){InitializeComponent();}privatestring s2;public Form2( string s1){InitializeComponent();s2= s1;}privatevoid Form2_Load(object sender, EventArgs e){textBox1.ReadOnly = true;textBox1.Text = "“" + s2 + "”" + "采用构造函数实现!";}}}using System;using System.Collections.Generic;using ponentModel; using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WinPassValue{publicpartialclass Form3 : Form {public Form3(){InitializeComponent();}privatestring ss;public Form3(TextBox te){InitializeComponent();ss = te.Text; ;}privatevoid Form3_Load(object sender, EventArgs e){textBox1.ReadOnly = true;textBox1.Text = "“" + ss + "”" + "采用传递控件的方式实现!";}}}using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WinPassValue{publicpartialclass Form4 : Form{public Form4(){InitializeComponent();}//定义委托publicdelegatestring PassValue();//定义事件publicevent PassValue MyEvent;//委托事件传值privatevoid Form4_Load(object sender, EventArgs e){textBox1.ReadOnly = true;textBox1.Text=MyEvent()+"委托事件传值实现!";}}}using System;using System.Collections.Generic; using ponentModel; using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WinPassValue{publicpartialclass Form5 : Form{public Form5(){InitializeComponent();}//Show方法重载!privatevoid Form5_Load(object sender, EventArgs e){MainForm mf=(MainForm)this.Owner;textBox1.Text = ((TextBox)mf.txtValue).Text+"采用Show方法重载方式实现!";}}}当然还有其他的方法,欢迎大家互相交流学习!。
在两个不同的Form窗体中的DataGridView数据“传递”在写程序时,遇到要在一个Form窗体中的DataGridView中选择数据,然后添加到另外一个Form窗体中的DataGridView中。
因为我想只点中某行的某个Cell就可以把这整行的内容取出来(即在某一行数据中,我随便点中一个Cell,就算选中了这整行数据)。
举个例子如下:首先我在左边选择一些Cell,然后添加就可以添加到右边那里:效果如下:下面是实现的代码:1、首先在主窗体调用子窗体的时候写这个(这里我是用一个按钮来触发):[csharp]view plaincopy1.private void addDatabaseButton_Click(object sender, Eve ntArgs e)2.{3.FactDatabaseForm factDB_Form = new FactDatabaseFor m();4.factDB_Form.Owner = this;5.factDB_Form.Show(); // 或者factDB_Form.ShowDialog();6.}2、在子窗体里面:[csharp]view plaincopy1.private void Form2_Load(object sender, EventArgs e)2.{3.mainForm = (MainForm)this.Owner; // 获得主窗体的引用4.mainCurDGV = mainForm.curDGV; // 获得主窗体中的那个DataGridView5.6.// TODO: This line of code loads data into the 'myDataSet .FactDB' table. You can move, or remove it, as needed.7.this.factDBTableAdapter.Fill(this.myDataSet.FactDB);8.}3、然后在按钮“把所选行增加到当前要推导的事实库中”的事件处理函数里面:[csharp]view plaincopy1.private void saveToCurFactDB_Click(object sender, EventA rgs e)2.{3.Dictionary<int, object> dicts = new Dictionary<int, objec t>();4.5.// 得到选中的行(不管是以整行选中,还是只是选中某行的某个单元,认为选中了该行),并且把这行的东西放到Dictionary里面6.int key;7.foreach (DataGridViewCell cell in this.factDatebaseDataGr idView.SelectedCells)8.{9.key = Convert.ToInt32(factDatebaseDataGridView.Rows[c ell.RowIndex].Cells[0].Value); // 得到该行中的那个"factID"10.if (!mainForm.mainDict.ContainsKey(key)) // 避免有重复11.{12.mainForm.mainDict.Add(key, factDatebaseDataGridVie w.Rows[cell.RowIndex].Cells[1].Value);13.dicts.Add(key, factDatebaseDataGridView.Rows[cell.Ro wIndex].Cells[1].Value);14.}15.}16.17.if(dicts.Count > 0) // 如果选择了一些在当前事实库没有的基才执行下面的18.{19.DataGridViewRow[] rows = new DataGridViewRow[dic ts.Count];20.foreach (var dict in dicts)21.{22.addItems(dict.Key, dict.Value as string);23.}24.25.mainCurDGV.Sort(mainCurDGV.Columns[0], ListSortDir ection.Ascending);26.MessageBox.Show("增加成功!", "消息");27.}28.else29.{30.MessageBox.Show("当前事实库已经存在你选择的这些事实", "提示");31.}32.}33.34.private void addItems(int iFactID, string strFactName)35.{36.//此处的代码不能进行循环!必须封装为一个方法,通过方法的循环,才能实现循环!37.DataGridViewRow dgvr = new DataGridViewRow();38.foreach (DataGridViewColumn c in this.factDatebaseD ataGridView.Columns)39.{40.dgvr.Cells.Add(c.CellTemplate.Clone() as DataGridView Cell);41.}42.dgvr.Cells[0].Value = iFactID;43.dgvr.Cells[1].Value = strFactName;44.mainCurDGV.Rows.Add(dgvr);45.}这里对上面代码再简单说明一下,如果要取得DataGridView中的某一行,可以这样写:[csharp]view plaincopy1.dataGridView.Rows[i];得到某一行的某个单元:[csharp]view plaincopy1.dataGridView.Rows[i].Cells[j]。
方法一:C#中没有了像中的全局变量,那么我们如何实现在不同的页面间传递参数呢?下面举例说明如何实现这一功能.1.新建一个项目.2.在该工程中添加一个窗体Form1.3.在该窗体中定义静态型字符串变量myTestStr1:public static string myTestStr1="";4.在该窗体的构造函数中对该变量进行赋值,并为该窗体类添加属性GetStrValue.public Form_Form1(){InitializeComponent();myTestStr1="Hello!";}public string GetStrValue{get{return myTestStr1;}set{myTestStr1=value;}}5.在该工程中另添加一个窗体Form2.6.在Form1窗体上添加一个button按钮(name:but_Test);7.在Form1窗体的but_Test_Click 事件中添加以下代码:private void but_Test_Click(object sender, System.EventArgs e){Form2 frm1=new Form2();frm1.ShowDialog(this) ;frm1.Close();}8.在Form2窗体上添加一个button按钮(name:but_Yes);9.在Form1窗体的but_Yes_Click 事件中添加以下代码:private void but_Yes_Click(object sender, System.EventArgs e){MessageBox.Show (Form_Form1.myTestStr1 ); //直接访问. 显示.结果:" Hello!"Form_Form1 frm2=new Form_Form1();frm2.GetStrValue ="How do you do?"; //生成一个新的实例对该静态变量进行操作(修改该静态变量的值).MessageBox.Show (frm2.GetStrValue ); //通过该实例的内部成员对它进行访问 .显示.结果: How do you do?"MessageBox.Show (Form_Form1.myTestStr1 ); //直接访问. 显示.结果:" How do you do?"}方法二:进入VS2005后,大家可以发现子窗体操作父窗体不能沿用2003下的方法:把父窗体的空间访问属性由private改为public.IDE已经把控件声明这部分代码隐藏了,所以只有采用更加对象一点的方法。
w inform窗体传值的几种方式(属性赋值,委托,事件)百度云盘代码下载:/share/link?shareid=388120&uk=3627406265 窗体设计:父窗体:子窗体:方法一:1、子窗体设置一个父窗体MainFrm属性:public MainFrm MainFrm { get; set; }2、在父窗体启动子窗体的时候:ChildFrm frm =new ChildFrm();frm.MainFrm = this;//将当前主窗体的实例传递给子窗体frm.Show();3、在子窗体同步按钮中://子窗体跟父窗体完全耦合在一块了。
MainFrm.txtName.Text = this.textBox1.Text;4、这样即可实现,在子窗体点击同步,子窗体文本框的值会同步到父窗体,但这种方式,子窗体跟父窗体完全耦合在一块了。
方法二、用委托来实现。
委托可以把一个方法作为参数带入另一个方法,在窗体传值中,子窗体需要执行一个方法来改变父窗体的值,而这个方法,则可以用委托从父窗体传递过来。
在父窗体中,声明修改文本框的方法AfterChildChange,在new一个子窗体的时候,将这个方法传递给子窗体。
那么当子窗体点击同步按钮时,会执行父窗体的AfterChildChange方法,已达到修改文本框值的目的。
1、在子窗体中设置一个委托类型的属性:public Action<string> AfterChangeTextDel { get; set; }2、在子窗体同步按钮中:if (AfterChangeTextDel != null){AfterChangeTextDel(this.textBox1.Text);//执行委托}3、在父窗体中添加方法:public void AfterChildChange(string text){txtName.Text = text;}4、在父窗体启动子窗体按钮:ChildFrm frm =new ChildFrm();frm.AfterChangeTextDel = new Action<string>(this.AfterChildChange);frm.Show();5、这样也能实现窗体传值,子窗体的委托可以在父窗体其他地方可以进行直接执行。
Winform 中多个窗口传值的问题解决相信很多像我一样的菜鸟,在学习C#,学习winform程序开发时,都或多或少的遇到过多个窗口之间传值的问题。
比如,有一个主窗口,同时还有一个子窗口用来对设置主窗口的字体样式,背景颜色等。
此时就涉及到一个问题:如何将子窗口设置的信息反映到主窗体中呢?!今天,我就以一个菜鸟的身份来说说我的解决办法,或许让老鸟们见笑了。
好吧,大致内容如下:我们假设现在有一个主窗口叫做MainWindow,还有一个窗口的名称叫做SubWindow。
并且一开始两个窗口是没有关系的。
我们在MainWindow上放置一个Button控件,Name属性设置为SettingButton,Text属性设置为:设置主窗口。
接下来,我们来设置SubWindow,首先,在SubWindow 上放置两个标签(因为就是个demo,所以尽量简洁为好。
)分别设置Text属性为:设置主窗体的Title属性:,设置主窗体的BackgroudColor属性。
同时在相应的标签后面添加TextBox控件,分别设置Name属性为:setMainWindowTitle, setMainWindowBackcolor。
接下来,给SubWindow添加一个Button控件,Name = “confirmButton”, Text = “确认设置”。
然后再SubWindow.cs中添加如下代码://添加属性,记录设置主窗体名称。
public string MainWindowTitle{get; set;}//添加属性,记录设置主窗体背景色的值public Color MainWindowBackColor{get; set;}下面我们来看方法一、我们通过在单击主窗体的Button后,将子窗体以Dialog窗口的方式显示出来,然后在Dialog窗体关闭后,再进行处理。
当然这种方法有个弊端,就是当子窗口显示时,主窗口不能操作。
前提:假设现在有两个窗口Form1和Form2, Form2是Form1的子窗口, 现在需要通过Form2来改变Form1中的内容效果:方法一:使用Delegate(代理)第一步:在Form2中定义代理并声明实例第二步:在Form1中定义用来代理的函数第三步:在Form1中生成Form2的实例并将代理赋值给Form2中的代理对象第四步:在Form2中调用代理总结:当Form2调用代理对象proEvent时实际上是在调用Form1中的Eventpro函数,由于Eventpro属于Form1,所以赋值成功。
方法二:使用自定义事件第一步:自定义事件第二步:在Form2中声明事件对象第三步:在Form1中定义事件回调函数第四步:创建Form2的对象实例,并将事件的回调函数添加到事件上(订阅事件)第五步:在Form2中的按钮上触发事件总结:当第五步事件被触发,事件对象Events会向所有订阅该事件的函数进行触发,而回调函数EventCallBack是Form1的成员,见第三步,所以数据传递成功。
利弊分析:第一种方法的优点显而易见,代理参数是可以自定义的,如:voidEventPro(string Message),其缺点就是,每一个这样的跨窗口调用都需要在子窗口中定义一个代理对象,并在主窗口中赋值相应的函数。
相对来说,我偏向于使用自定义事件,首先,不是所有学过winform的人都接触过这部分内容(高端大气上档次),其次,他可以实现一个函数向n个窗口传值,只要给事件添加订阅就可以了,frm.Events += new EventHandler<MyEventArgs>(EventCallBack)。
(方便)。
另外,看过winform下层代码的人会发现,事件处理数据的次数往往不止一次,当事件发生时,先由内部处理,再交给外部。
我们可以在MyEventArgs的构造函数中先对事件进行处理,再发布出去,看起来更好。
首先定义两个Form,一个为Form1,一个为Form2,其中Form1作为父窗口,Form2作为子窗口
1、父窗口传值给子窗口
Form1中代码:
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 lForm = new Form2();//实例化一个Form2窗口
lForm.String1 = "传值给子窗口Form2成功";//设置Form2中string1的值
lForm.SetValue();//设置Form2中Label1的
lForm.ShowDialog();
}
Form2中代码:
private string string1;
public string String1
{
set
{
string1 = value;
}
}
public void SetValue()
{
bel1.Text = string1;
}
public Form2()
{
InitializeComponent();
}
2、子窗口返回值给父窗口
Form1中代码:
public Form1()
{
InitializeComponent();
}
private string strValue;
public string StrValue
{
set
{
strValue = value;
}
}
private void btnShowForm2_Click(object sender, EventArgs e)
{
Form2 lForm = new Form2();
lForm.Owner = this;//重要的一步,主要是使Form2的Owner指针指向Form1 lForm.ShowDialog();
MessageBox.Show(strValue);//显示返回的值
}
From2中代码:
public Form2()
{
InitializeComponent();
}
private void btnClose_Click(object sender, EventArgs e)
{
Form1 lForm1 = (Form1)this.Owner;//把Form2的父窗口指针赋给lForm1 lForm1.StrValue = "子窗口Form2返回数值成功";//使用父窗口指针赋值this.Close();
}
winForm:利用窗体的自定义属性实现窗体传值
第1步:在解决方案上添加一个窗体Form2;并添加textBox1、textBox2、Button1,将Button1的标题设为“确定”,DialogResult属性设为“OK”;
第2步:在窗体Form2的类代码中添加两个私有字段: _username、_password,并添加两个public 属性:UserName、Password;代码如下:
public partial class Form2: Form
{
private string _username;
private string _password;
public string UserName
{
get
{
return _username;
}
set
{
_username=value;
}
}
public string Password
{
get
{
return _password;
}
set
{
_password=value;
}
}
.....
}
第3步:窗体间相互传值演示
在Form1添加一个的Botton1、一个comboBox1,在Botton1_Click函数中如下代码:private void button1_Click(object sender,EventArgs e)
{
Form2 myForm2= new Form2();
erName="Richard";//Form1向Form2传值!!!
myForm2.Password="pwd1234";
DialogResult result= myForm2.ShowDialog();
if(result==DialogResult.OK)
{
comboBox1.Items.Add(erName);////Form2向Form1传值!!!
comboBox2.Items.Add(myForm2.Password);
}
}
要充分演示上述功能,还需要对Form2的代码作如下完善:
第1,在Form2_Load中添加如下代码:
private Form2_Load(object sender,EventArgs e)
{
textBox1.Text=_username;
textBox2.Text=_password;
}
第2,在textBox1、textBox2的textChanged事件中添加如下代码:
private void textBox1_TextChanged(object sender,EventArgs e) {
erName=textBox1.Text;
}
private void textBox2_TextChanged(object sender,EventArgs e) {
this.Password=textBox2.Text;
}。