logo资料库

在.net中轻松掌控windows窗体间的数据交互.doc

第1页 / 共31页
第2页 / 共31页
第3页 / 共31页
第4页 / 共31页
第5页 / 共31页
第6页 / 共31页
第7页 / 共31页
第8页 / 共31页
资料共31页,剩余部分请下载后查看
 在.net 中轻松掌控 windows 窗体间的数据交互(一) zhzuo(秋枫) windows 窗体是用于 microsoft windows 应用程式研发的、基于 .net framework 的新平台。此框架提供 一个有条理的、面向对象的、可扩展的类集,他使你得以研发丰富的 windows 应用程式。一个 windows 窗体就代表了.net 架构里的 system.windows.forms.form 类的一个实例。 作者在 csdn 技术论坛.net 板块下的 c#分类经常看到有人问起怎么在两个 form 间传递数据,访问修改对方 窗体里面的值。对于有经验的程式员来说不是什么高深的东西,而对于初学者来说这些基础的东西往往是 个问题,并且存在这种现象,往往比较复杂的东西他们会,要用什么了就去学什么,实际上并没有真正的 去理解掌控他,基础不扎实,所以就有了想通过自己对窗体编程积累的经验来写一些这方面的文章,以供 学.net 的朋友参考,也借此机会同各位朋友进行交流,写得不合理的地方请各位朋友提宝贵意见,下面我 分了三个部分来讲。 一.使用带参数的构造函数 我们要做的准备工作就是新建两个窗体,下面是两个窗体的布局,非常简单: <第一个例子> 说明:form1 为主窗体,包含控件:文本框 textboxfrm1,多选框 checkboxfrm1 和按钮 buttonedit; form2 为子窗体,包含控件:文本框 textboxfrm2,多选框 checkboxfrm2 和按钮 buttonok,buttoncancel。 当我们新建一个窗体的时候,设计器会生成默认的构造函数: public form2() { initializecomponent(); }
他不带参数,既然我们要把 form1 中的一些数据传到 form2 中去,为什么不在 form2 的构造函数里做文章 呢? 假设我们要实现使 form2 中的文本框显示 form1 里 textboxfrm1 的值,修改子窗体的构造函数: public form2(string text) { initializecomponent(); this.textboxfrm2.text = text; } 增加 form1 中的修改按钮点击事件,处理函数如下: private void buttonedit_click(object sender, system.eventargs e) { form2 formchild = new form2(this.textboxfrm1.text); formchild.show(); } 我们把 this.textboxfrm1.text 作为参数传到子窗体构造函数,以非模式方式打开,这样打开的 formchild 的 文本框就显示了”主窗体”文本,是不是非常简单,接下来我们传一个 boolean 数据给子窗体。 public form2(string text,bool checkedvalue) { initializecomponent();
this.textboxfrm2.text = text; this.checkboxfrm2.checked = checkedvalue; } 在主窗体中的修改按钮点击处理,我采用了打开模式窗口的方式,其实在这个例子中看不出有什么分别, private void buttonedit_click(object sender, system.eventargs e) { form2 formchild = new form2(this.textboxfrm1.text,this.checkboxfrm1.checked); formchild.showdialog(); } 结果在预料之中,不过这里明显存在不足,在子窗体里的数据修改后不能传给主窗体,也就是说主窗体不 受子窗体的影响。而在实际的研发过程中我们经常使用子窗体来修改主窗体里面的数据,那怎么解决呢? 在.net 中有两种类型,值类型和引用类型。值类型是从 valuetype 继承而来,而 valuetype 又是从 object 继承;对于引用类型他直接继承 object 类型。这下让我们看看怎样通过 form2 来修改 form1 里的数据。 还是让我们来修改 form2 的代码。 private textbox textboxfrm12; private checkbox checkboxfrm12; public form2(textbox heckbo,checkbox heckbox) { initializecomponent(); this.textboxfrm2.text = heckbo.text;
this.checkboxfrm2.checked = heckbox.checked; this.textboxfrm12 = heckbo; this.checkboxfrm12 = heckbox; } 目前我们传了两个引用类型的数据:textbox 类型,和 checkbox;另外在 form2 中增加了两个类数据成员 textboxfrm12、checkboxfrm12 用来分别保存构造函数传来的变量,不过他们并不属于 form2 的 controls 容器。修改 form2 的确定按钮点击事件函数: private void buttonok_click(object sender, system.eventargs e) { this.textboxfrm12.text = this.textboxfrm2.text; this.checkboxfrm12.checked = this.checkboxfrm2.checked; this.close(); } 上面的代码我们通过把 textboxfrm2 的 text 和 checkboxfrm2.checked 赋给 textboxfrm12 和 checkboxfrm12 完成了对主窗体中的 textboxfrm1 和 checkboxfrm2 的修改,因为 textboxfrm1 和 textboxfrm12 是同一个引 用,而 checkboxfrm2 和 checkboxfrm12 也是。 到这里为止功能是实现了,不过总觉得不是非常合理,让两个窗体控件传来传去,目前我举一个恰当一点 的例子。 修改了两个窗体: <第二个例子>
说明:在这个例子中我们的两个窗体都加了一个 listbox 用来显示 arraylist 中的内容。 主窗体中控件:listboxfrm1,buttonedit; 子窗体中控件:listboxfrm2,textboxadd,buttonadd,buttonedit,buttonok。 这次我们用 arraylist 来作为传递数据,在 form1 中定义类数据成员: private arraylist listdata1; 在构造函数中增加了对 listdata1 进行内存分配,并生成数据最终绑定到 listboxfrm1, public form1() { initializecomponent(); this.listdata1 = new arraylist(); this.listdata1.add("dotnet"); this.listdata1.add("c#"); this.listdata1.add("asp.net"); this.listdata1.add("webservice"); this.listdata1.add("xml"); this.listboxfrm1.datasource = this.listdata1; } 另外,对修改按钮点击事件处理函数的修改如下:
private void buttonedit_click(object sender, system.eventargs e) { form2 formchild = new form2(this.listdata1); formchild.showdialog(); this.listboxfrm1.datasource = null; this.listboxfrm1.datasource = this.listdata1; } 相对和主窗体,对子窗体作相应修改,也在 form2 中增加了类数据成员: private arraylist listdata2; 用来保存对主窗体中 listdata1 的引用。 修改构造函数: public form2(arraylist listdata) { initializecomponent(); this.listdata2 = listdata; foreach(object o in this.listdata2) { this.listboxfrm2.items.add(o); }
} 这里让 listdata2 同 listdata1 指向同一个引用;另外没有对 listboxfrm 进行绑定,采用了填充。 好了,下面是对数据操作的时候了。 添加处理函数代码如下: private void buttonadd_click(object sender, system.eventargs e) { if(this.textboxadd.text.trim().length>0) { this.listdata2.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) { this.listdata2.removeat(index); this.listboxfrm2.items.removeat(index); } else messagebox.show("请选择删除项或没有可删除的项!"); } 退出 form2 子窗体: private void buttonok_click(object sender, system.eventargs e) { this.close(); } 编译运行程式,在子窗体中对数据进行修改,关闭后,主窗体就会显示更新后的数据。 这里有一点要提醒一下,比较两个例子,我们都传的是引用类型,一个是 string,另一个是 arraylist,为什 么 string 类型不能修改主窗体的数据呢?其实在.net 中对 string 类型的修改并不是修改原来的值,原来的 值没有变化,而是重新生成一个新的字符串,下面是个非常好的说明。 public class zzconsole { [stathread]
分享到:
收藏