窗体间传递复杂数据

窗体间传递复杂数据

源代码下载请点这里

在设计窗体程序时往往需要相互调用的窗体间传递复杂的数据,有时候甚至需要子窗体修改父窗体的内容。前一阵在博客园中看到很多人讨论这个问题,在海天一鸥《窗体间传值和窗体间互操作》的评论中,我看到有这么几种做法:1)公开一个静态变量;2)在子窗体中创建一个公有字段;3)在父窗体中使用委托与事件;4)将子窗体作为父窗体成员。

这些办法我感觉都不是特别好,会导致父窗体与子窗体耦合过于紧密,对任何一个窗体的修改需要重新编译另外一个窗体。根据“依赖倒置”的原则,通过引入一个结果对象,就可以避免这种紧耦合,同时也可以传递任意复杂的数据。如果需要在子窗体中改变父窗体状态,也可以在这个结果对象中定义委托与事件来达到目的。我在这里给出我的解决方案。

首先定义一个结果对象,用来存放子窗体返回的结果。同时定义一些事件,可以让子窗体修改父窗体的状态。代码如下:

None.gif using  System;
None.gif
None.gif
namespace  WinParam
ExpandedBlockStart.gif
{
InBlock.gif   
public delegate void TextChangedHandler(string s);
InBlock.gif
InBlock.gif   
public class cResult
ExpandedSubBlockStart.gif   
{
InBlock.gif      
public string Result1 = "";
InBlock.gif      
public string Result2 = "";
InBlock.gif      
InBlock.gif      
public event TextChangedHandler TextChanged;
InBlock.gif
InBlock.gif      
public void ChangeText(string s)
ExpandedSubBlockStart.gif      
{
InBlock.gif         
if(TextChanged != null)
InBlock.gif            TextChanged(s);
ExpandedSubBlockEnd.gif      }

ExpandedSubBlockEnd.gif   }

ExpandedBlockEnd.gif}

添加一子窗体构造函数,允许接收一结果对象:

None.gif private  cResult r;
None.gif
None.gif
public  frmChild(cResult r): this ()
ExpandedBlockStart.gif
{
InBlock.gif   
this.r = r;            
ExpandedBlockEnd.gif}

在父窗体中创建子窗体,并订阅cResult事件:

None.gif private   void  btnCallChild_Click( object  sender, System.EventArgs e)
ExpandedBlockStart.gif
{
InBlock.gif   cResult r 
= new cResult();
InBlock.gif   r.TextChanged 
+= new TextChangedHandler(this.EventResultChanged);
InBlock.gif   frmChild fc 
= new frmChild(r);
InBlock.gif   fc.ShowDialog();
InBlock.gif   txtCallResult.Text 
= "The Result is: " + r.Result1 + " " + r.Result2;
ExpandedBlockEnd.gif}

None.gif
None.gif
private   void  EventResultChanged( string  s)
ExpandedBlockStart.gif
{
InBlock.gif   txtEventResult.Text 
= s;
ExpandedBlockEnd.gif}

这样确保父窗体知道子窗体,而子窗体不知道父窗体。父窗体改变后不需要重新编译子窗体。同时两个窗体都依赖于结果对象,结果对象的稳定性也决定了父窗体与子窗体关系的稳定性。下面是程序运行结果:

窗体间传递复杂数据_第1张图片

注:提供的代码仅仅是功能演示,如果实际使用需要添加一些额外辅助代码(对象释放、取消事件订阅等)。
posted on 2004-08-17 10:28 吕震宇 阅读(470) 评论(12)   编辑  收藏

评论

 re: 窗体间传递复杂数据 2004-08-17 11:19
收藏

 re: 窗体间传递复杂数据 2004-08-17 11:34
很怀念Visual FoxPro,上面的这种做法是从VFP提供的数据导航工具条源码中学到的。VFP用这种办法一次返回多个结果。

 re: 窗体间传递复杂数据 2004-08-17 12:06
这个办法真好啊!

最近作一个MDA工具的开发,将模型导出为XML,然后用生成器将XML导出为JSP+serverlet或者 ASP.NET页面。

其中 ,建模器是典型的将UI信息转入到后台模型对象,这个过程涉及很多窗体间信息的传递,但都是操作同一个对象。

目前为了赶进度,整个框架设计的并不好,冗余代码多,复用的少,解决方案并不好。

我希望在1.0版完成后,在下一个版本中,大幅度更改架构:
1.使用 对象管理器 的概念,UI完全与后台XML数据模型对象解偶。
2. 对象的序列化功能使用模版方法,因为大多数对象的字段序列化代码都是差不多的,如果有模版方法,可以少写很多代码。
3.改进窗体传值



 re: 窗体间传递复杂数据 2004-08-21 16:03
好东西

 re: 窗体间传递复杂数据 2004-08-27 16:49
收藏

 re: 窗体间传递复杂数据 2004-09-03 16:21
收藏

 re: 窗体间传递复杂数据 2004-09-03 16:28
好东西

 re: 窗体间传递复杂数据 2004-09-20 16:49


 re: 窗体间传递复杂数据 2004-09-20 16:55
不行,我得多夸两句,这个东西我做了两天还没做出来。真感谢!

 re: 窗体间传递复杂数据 2004-10-17 14:48
我是初学者,冒昧问一句,这样做跟改变一个变量的值比不是多了好多代码了,这样有什么好处??

 re: 窗体间传递复杂数据 2004-10-17 14:51
对象释放、取消事件订阅等这样又是放在什么地方,需要怎么做呢??

 re: 窗体间传递复杂数据 2004-10-17 19:15
@C#初学

为了让系统更为稳定,通常程序在编写时都遵循高内聚,松耦合的原则。虽然代码复杂了很多,但保证了松耦合。这样当两个窗体的代码发生变化时,不至于对另外一个窗体产生影响。

释放、取消事件订阅通常在子窗体释放时调用。

你可能感兴趣的:(技术文章,string,c#,asp.net,xml,工具,object)