Windows 窗体是用于 Microsoft Windows 应用程序开发的基于 NET Framework 的新平台此框架提供一个有条理的面向对象的可扩展的类集它使您得以开发丰富的 Windows 应用程序一个Windows窗体就代表了NET架构里的SystemWindowsFormsForm类的一个实例
作者在CSDN技术论坛NET板块下的C#分类经常看到有人问起如何在两个Form间传递数据访问修改对方窗体里面的值对于有经验的程序员来说不是什么高深的东西而对于初学者来说这些基础的东西往往是一个问题并且存在这种现象往往比较复杂的东西他们会要用什么了就去学什么实际上并没有真正的去理解掌握它基础不扎实所以就有了想通过自己对窗体编程积累的经验来写一些这方面的文章以供学NET的朋友参考也借此机会同各位朋友进行交流写得不合理的地方请各位朋友提宝贵意见下面我分了三个部分来讲
一.使用带参数的构造函数
我们要做的准备工作就是新建两个窗体下面是两个窗体的布局很简单
说明Form为主窗体包含控件文本框textBoxFrm多选框checkBoxFrm和按钮buttonEdit
Form为子窗体包含控件文本框textBoxFrm多选框checkBoxFrm和按钮buttonOKbuttonCancel
当我们新建一个窗体的时候设计器会生成默认的构造函数
public Form()
{
InitializeComponent();
}
它不带参数既然我们要把Form中的一些数据传到Form中去为什么不在Form的构造函数里做文章呢?
假设我们要实现使Form中的文本框显示Form里textBoxFrm的值修改子窗体的构造函数
public Form(string text)
{
InitializeComponent();
thistextBoxFrmText = text;
}
增加Form中的修改按钮点击事件处理函数如下
private void buttonEdit_Click(object sender SystemEventArgs e)
{
Form formChild = new Form(thistextBoxFrmText);
formChildShow();
}
我们把thistextBoxFrmText作为参数传到子窗体构造函数以非模式方式打开这样打开的formChild的文本框就显示了主窗体文本是不是很简单接下来我们传一个boolean数据给子窗体
Public Form(string textbool checkedValue)
{
InitializeComponent();
thistextBoxFrmText = text;
thischeckBoxFrmChecked = checkedValue;
}
在主窗体中的修改按钮点击处理我采用了打开模式窗口的方式其实在这个例子中看不出有什么分别
private void buttonEdit_Click(object sender SystemEventArgs e)
{
Form formChild = new Form(thistextBoxFrmTextthischeckBoxFrmChecked);
formChildShowDialog();
}
结果在预料之中但是这里明显存在不足在子窗体里的数据修改后不能传给主窗体也就是说主窗体不受子窗体的影响而在实际的开发过程中我们经常使用子窗体来修改主窗体里面的数据那怎么解决呢?
在NET中有两种类型值类型和引用类型值类型是从ValueType继承而来而ValueType又是从Object继承对于引用类型它直接继承Object类型这下让我们看看怎样通过Form来修改Form里的数据
还是让我们来修改Form的代码
Private TextBox textBoxFrm;
private CheckBox checkBoxFrm;
public Form(TextBox heckboCheckBox heckbox)
{
InitializeComponent();
thistextBoxFrmText = heckboText;
thischeckBoxFrmChecked = heckboxChecked;
thistextBoxFrm = heckbo;
thischeckBoxFrm = heckbox;
}
现在我们传了两个引用类型的数据TextBox类型和CheckBox另外在Form中增加了两个类数据成员textBoxFrmcheckBoxFrm用来分别保存构造函数传来的变量不过他们并不属于Form的Controls容器修改Form的确定按钮点击事件函数
private void buttonOK_Click(object sender SystemEventArgs e)
{
thistextBoxFrmText = thistextBoxFrmText;
thischeckBoxFrmChecked = thischeckBoxFrmChecked;
thisClose();
}
上面的代码我们通过把textBoxFrm的Text和checkBoxFrmChecked赋给textBoxFrm和checkBoxFrm完成了对主窗体中的textBoxFrm和checkBoxFrm的修改因为textBoxFrm和textBoxFrm是同一个引用而checkBoxFrm和checkBoxFrm也是
到这里为止功能是实现了但是总觉得不是很合理让两个窗体控件传来传去现在我举一个恰当一点的例子
修改了两个窗体
说明在这个例子中我们的两个窗体都加了一个ListBox用来显示ArrayList中的内容
主窗体中控件listBoxFrmbuttonEdit
子窗体中控件listBoxFrmtextBoxAddbuttonAddbuttonEditbuttonOK
这次我们用ArrayList来作为传递数据在Form中定义类数据成员
private ArrayList listData;
在构造函数中增加了对listData进行内存分配并生成数据最终绑定到listBoxFrm
public Form()
{
InitializeComponent();
thislistData = new ArrayList();
thislistDataAdd(DotNet);
thislistDataAdd(C#);
thislistDataAdd();
thislistDataAdd(WebService);
thislistDataAdd(XML);
thislistBoxFrmDataSource = thislistData;
}
另外对修改按钮点击事件处理函数的修改如下
private void buttonEdit_Click(object sender SystemEventArgs e)
{
Form formChild = new Form(thislistData);
formChildShowDialog();
thislistBoxFrmDataSource = null;
thislistBoxFrmDataSource = thislistData;
}
相对与主窗体对子窗体作相应修改也在Form中增加了类数据成员
private ArrayList listData;
用来保存对主窗体中listData的引用
修改构造函数
public Form(ArrayList listData)
{
InitializeComponent();
thislistData = listData;
foreach(object o in thislistData)
{
thislistBoxFrmItemsAdd(o);
}
}
这里让listData同listData指向同一个引用另外没有对listBoxFrm进行绑定采用了填充
好了下面是对数据操作的时候了
添加处理函数代码如下
private void buttonAdd_Click(object sender SystemEventArgs e)
{
if(thistextBoxAddTextTrim()Length>)
{
thislistDataAdd(thistextBoxAddTextTrim());
thislistBoxFrmItemsAdd(thistextBoxAddTextTrim());
}
else
MessageBoxShow(请输入添加的内容!);
}
删除处理代码如下
private void buttonDel_Click(object sender SystemEventArgs e)
{
int index = thislistBoxFrmSelectedIndex;
if(index!=)
{
thislistDataRemoveAt(index);
thislistBoxFrmItemsRemoveAt(index);
}
else
MessageBoxShow(请选择删除项或者没有可删除的项!);
}
退出Form子窗体
private void buttonOK_Click(object sender SystemEventArgs e)
{
thisClose();
}
编译运行程序在子窗体中对数据进行修改关闭后主窗体就会显示更新后的数据
这里有一点要提醒一下比较两个例子我们都传的是引用类型一个是String另一个是ArrayList为什么string类型不能修改主窗体的数据呢?其实在Net中对string类型的修改并不是修改原来的值原来的值没有变化而是重新生成一个新的字符串下面是一个很好的说明
public class ZZConsole
{
[STAThread]
static void Main(string[] args)
{
string str = abc;
string str = str;
str = ;
ConsoleWriteLine(str);
ConsoleWriteLine();
ConsoleWriteLine(str);
ConsoleWriteLine();
ArrayList al = new ArrayList();
alAdd(abc);
ArrayList al = al;
alAdd();
foreach(object o in al)
ConsoleWriteLine((string)o);
ConsoleWriteLine();
foreach(object o in al)
ConsoleWriteLine((string)o);
ConsoleReadLine();