C#窗口间传递消息

链接http://blog.csdn.net/chenyuling/archive/2007/05/25/1625907.aspx

我用的方法是:见下面我在白云的帖子

发信人: CCBB (超超饱饱|酒饱饭足~~), 信区: DotNet
标  题: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月04日22:03:00 星期三)

一个主窗口MainForm和一个对话框窗口DialogForm。主窗口通过一个菜单项调出对话框窗
口。对话框窗口有个保存按钮,点击保存按钮后,对话框关闭,并且将保存信息存入文件
中。
问题是:当点击保存按钮后,如何告知MainForm这个消息呢,我想要点击保存后就能在Mi
anForm上显示修改后的信息。
本来想在MainForm中设一个static变量,点击保存按钮把消息传给这个变量,但是点击之
后又如何立刻知道这个变量被修改了呢?

--

You are beautiful, You are beautiful, it's true.

But it's time to face the truth...I will never be with you...

  ╭———╮

※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·

 

发信人: joshuaG (Big G|Solution, Revolution, Evolution), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月04日22:11:13 星期三), 站内信件

例如说你要把对话框里的一个TextBox的文本保存在MainForm里头,这样

假设这个TextBox是_tb

在DialogForm中定义一个Property:

public string Data { get{return _tb.Text;}}

同时把保存按钮的DialogResult属性设置为OK

然后在MainForm的打开对话框的方法中写

DialogForm frm=new DialogForm();
if(frm.ShowDialog()==DialogResult.OK)
    val = frm.Data;

其中val是你要赋值的变量 

【 在 CCBB (超超饱饱|酒饱饭足~~) 的大作中提到: 】
: 一个主窗口MainForm和一个对话框窗口DialogForm。主窗口通过一个菜单项调出对话框窗
: 口。对话框窗口有个保存按钮,点击保存按钮后,对话框关闭,并且将保存信息存入文件
: 中。
: 问题是:当点击保存按钮后,如何告知MainForm这个消息呢,我想要点击保存后就能在Mi
: anForm上显示修改后的信息。
: 本来想在MainForm中设一个static变量,点击保存按钮把消息传给这个变量,但是点击之
: 后又如何立刻知道这个变量被修改了呢?

--
                有四类人
                积极采取行动促使事件发生的人
                被动接受所发生事件的人
                对事件持旁观者心态的人
                什么事也不关心的人
                而我要做的当然是第一种人,能做出变革和业绩的人 
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·

 

发信人: CCBB (超超饱饱|酒饱饭足~~), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月04日22:27:08 星期三)

明白了,用个DialogResult属性...多谢~!!
【 在 joshuaG 的大作中提到: 】
: 例如说你要把对话框里的一个TextBox的文本保存在MainForm里头,这样
: 假设这个TextBox是_tb
: 在DialogForm中定义一个Property:
--
You are beautiful, You are beautiful, it's true.
  ╭———╮
  │╯╰ │
  │ 口 ├┬—╮
  ╰——┬╯│╭╯
  ╯ ╯╰—

※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·

 

发信人: hustorochi (Mark Zhou), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月09日20:48:08 星期一)

请使用事件解决此问题。

首先需要在 Dialogform 中声明如下事件和函数。

public event EventHandler SavedData;

protected virtual void OnSavedData(EventArgs e)
{
    if (this.SavedData != null)
    {
        this.SavedData(e);
    }
}

然后在"保存"按钮处理事件中引发该事件。

private void OnSaveButtonClick(object sender, EventArgs e)
{
    // TODO: Save your data.
    WriteDataToFile();
    OnSavedData(new EventArgs());
}

最后在 MainForm 打开对话框的时候。

public void OnOpenDialogMenuItemClick(object sender, EventArgs e)
{
    DialogForm form = new DialogForm();
    // Subscribe the SavedData event.
    form.SavedData += (_sender, _e) => RefreshData();
    form.ShowDialog();
}

请尽量减少使用通过 ShowDialog() 的返回值 DialogResult 判断商业逻辑。这样会导致
无法维护的代码增加。

【 在 CCBB 的大作中提到: 】
: 一个主窗口MainForm和一个对话框窗口DialogForm。主窗口通过一个菜单项调出对话..
: 口。对话框窗口有个保存按钮,点击保存按钮后,对话框关闭,并且将保存信息存入..
: 中。

--
Mark Zhou
Software Design Engineer (SDE)
Solution Delivery Engineer at Microsoft
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·

 

发信人: joshuaG (G | 我们如何才能更加了解彼此呢?), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月09日22:28:41 星期一), 站内信件

学习了
【 在 hustorochi (Mark Zhou) 的大作中提到: 】
: 
: 请使用事件解决此问题。
: 
: 首先需要在 Dialogform 中声明如下事件和函数。
: 
: public event EventHandler SavedData;
: 
--

I Love Rock & Roll

    I Love Art & War
http://newhost.byhh.net/f/DotNet/1161499057/eyes.jpg
        I Love U After All 
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·

 

 
发信人: doubleclick (强悍地解释人生), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月09日23:38:16 星期一), 站内信件

融哥能否谈谈 "请尽量减少使用通过 ShowDialog() 的返回值 DialogResult 判断商业逻
辑。这样会导致
无法维护的代码增加。" 这具体是如何引起的? 另外就楼主这个问题,这里为什么不用for
m2的构造器直接传参数进去? 

谢谢

【 在 hustorochi (Mark Zhou) 的大作中提到: 】: 
: 请使用事件解决此问题。
: 
: 首先需要在 Dialogform 中声明如下事件和函数。
: 
: public event EventHandler SavedData;
: 
: protected virtual void OnSavedData(EventArgs e)
: {
:     if (this.SavedData != null)
: .................(以下省略)

--
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·[FROM: fox23.cnblogs.com

 

发信人: yuxhust (happy fish), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月10日16:33:37 星期二)

按LZ的需求,也可以用MDIParent窗体
【 在 CCBB 的大作中提到: 】
: 一个主窗口MainForm和一个对话框窗口DialogForm。主窗口通过一个菜单项调出对话..
: 口。对话框窗口有个保存按钮,点击保存按钮后,对话框关闭,并且将保存信息存入..
: 中。
: 问题是:当点击保存按钮后,如何告知MainForm这个消息呢,我想要点击保存后就能..

--
http://newhost.byhh.net/f/Picture/1234163724/2009_2_9_151323.bmp
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·

 

 
发信人: joshuaG (G|想念变成一条线 在时间里面蔓延), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月10日16:34:20 星期二), 站内信件

MDI是用于多文档的,用在这种Dialog上面显然不合适。

【 在 yuxhust (happy fish) 的大作中提到: 】
: 按LZ的需求,也可以用MDIParent窗体
: 【 在 CCBB 的大作中提到: 】
: : 一个主窗口MainForm和一个对话框窗口DialogForm。主窗口通过一个菜单项调出对话..
: : 口。对话框窗口有个保存按钮,点击保存按钮后,对话框关闭,并且将保存信息存入..
: : 中。
: : 问题是:当点击保存按钮后,如何告知MainForm这个消息呢,我想要点击保存后就能..

--
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·[FROM:Utopian Blue]

 

 
发信人: yayxcn (羊肉贩子): 贩卖羊肉和代码 (oh Yannic!), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月11日00:32:29 星期三), 站内信件

~这个非常好
可以算是一个利用事件的最佳实践吧
事件或者观察者模式在这里产生的松耦合是非常有意义的

【 在 hustorochi (Mark Zhou) 的大作中提到: 】
: 
: 请使用事件解决此问题。
: 
: 首先需要在 Dialogform 中声明如下事件和函数。
: 
: public event EventHandler SavedData;
: 

--

    上善若水
    水利万物而不争
Hello you, Hello me, Hello World...
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·

 

 

 
发信人: yayxcn (羊肉贩子): 贩卖羊肉和代码 (oh Yannic!), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月11日00:39:30 星期三), 站内信件

DialogResult也就用CommonDialog时候好用

自己定义的DialogForm形式多样,DialogResult并不是一个必须的东西,不是规范

所以完全没有办法保证自定义的DialogForm会返回这么个对象

换句话说

如果在主程序里面试用了DialogResult,那么主程序就对DialogForm有了依赖,依赖来
自于DialogResult

lz的问题看情况

我觉得如果是利用一个DialogForm修改一个全局的值,设置主窗体的static变量或者使
用单例模式存储全局变量就可以了

如果是需要对局部变量在DialogForm中进行计算处理等工作,返回处理的值,完全可以
用构造器参数,但是无论何种方法都没有提供值改变通知功能

因此需要添加一个SavedData事件来反向通知调用者值的变化,主程序可以通过订阅事件
刷新数据,这也就是上面程序解决的问题

【 在 doubleclick (强悍地解释人生) 的大作中提到: 】
: 融哥能否谈谈 "请尽量减少使用通过 ShowDialog() 的返回值 DialogResult 判断商业逻
: 辑。这样会导致
: 无法维护的代码增加。" 这具体是如何引起的? 另外就楼主这个问题,这里为什么不用for
: m2的构造器直接传参数进去? 
: 谢谢

--

    上善若水
    水利万物而不争
Hello you, Hello me, Hello World...
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·

 

 
发信人: hustorochi (Mark Zhou), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月11日12:57:17 星期三)

我们在编写程序的时候,应该尽量减少组件之间的偶合性,对于 DialogResult,它依赖于
 ModalDialog,如果程序显示的是一个 Modaless Dialog,那么 DialogResult 不产生任
何值,从而 UI 的改变导致了代码的改变。

另一方面,我也不推荐通过构造函数对 UI 组件传递数据。构造函数是用来对其所描述的
类进行实例化的,而不是用来传递数据的;换句话说,构造函数应该干他应该干的事情。
利用构造函数把一个数据传进来,而该数据跟这个类(System.Windows.Forms.Form)没有直
接关系,那么这就是 Data Corruption。

所以,这里最好的设计模式就是 Subscribe -> Observer。

【 在 yayxcn 的大作中提到: 】
: DialogResult也就用CommonDialog时候好用
: 自己定义的DialogForm形式多样,DialogResult并不是一个必须的东西,不是规范
: 所以完全没有办法保证自定义的DialogForm会返回这么个对象
: 换句话说
: 如果在主程序里面试用了DialogResult,那么主程序就对DialogForm有了依赖,依赖..
: 自于DialogResult
: lz的问题看情况

--
Mark Zhou
Software Design Engineer (SDE)
Solution Delivery Engineer at Microsoft
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·

 

 
发信人: wpboy (我爱抬杠,但我更爱真理), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月11日13:05:32 星期三), 站内信件

我以前写代码很有洁癖,觉得就应该用正确的优雅的方法。
然后偶然发现好比“单身宿舍”,如果不考虑以后扩展为
两人世界三口之家的,为啥搞这么干净,人活得多累啊。
很多人写的小程序可能也就他自己用用,别人都不会去维
护的,更不会去扩展,所以能以最简单的方法搞定即可。
有时太多的模式啊框架啊,对于我们这种入门级的,还是
很有难度的。是吧,加菲~~敲这么多字不容易

【 在 hustorochi (Mark Zhou) 的大作中提到: 】
: 
: 我们在编写程序的时候,应该尽量减少组件之间的偶合性,对于 DialogResult,它依赖于
:  ModalDialog,如果程序显示的是一个 Modaless Dialog,那么 DialogResult 不产生任
: 何值,从而 UI 的改变导致了代码的改变。
: 
: 另一方面,我也不推荐通过构造函数对 UI 组件传递数据。构造函数是用来对其所描述的
: 类进行实例化的,而不是用来传递数据的;换句话说,构造函数应该干他应该干的事情。
: 利用构造函数把一个数据传进来,而该数据跟这个类(System.Windows.Forms.Form)没有直
: 接关系,那么这就是 Data Corruption。
: 
: .................(以下省略)

--
博士第一年:我要当一个牛博士        
博士第二年:我要三年毕业            
博士第三年:我要四年毕业            
博士第四年:爱怎么着就怎么着吧      
博士第……:苦海无边回头是岸        
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·

 

 
 
发信人: yayxcn (羊肉贩子): 贩卖羊肉和代码 (oh Yannic!), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月11日16:13:54 星期三), 站内信件

是 难度肯定是有
模式啊框架啊什么的
就是前人总结的经验
就是写了n多代码总结出来的最好的方式,所谓的最佳实践,这么搞总体效率最高,所以才
这样
如果是本着自己用用不维护的目的,自然也就无所谓模式框架什么的
不过如果是工业化的开发,不是玩玩的代码,这些模式啊框架啊就是极其有用了

但是写代码可以没有洁癖,但不能不爱干净
--

    上善若水
    水利万物而不争
Hello you, Hello me, Hello World...
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·

 

 
 
发信人: yayxcn (羊肉贩子): 贩卖羊肉和代码 (oh Yannic!), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月11日16:30:12 星期三), 站内信件

UI组件 和 数据 的绑定说到点上了。。。
我觉得这地方也不用完全追求分离
其实Winform里面UI组件和数据本来就是在一起的
比如xxxForm类里面经常有个类似RefreshData方法,从理论上来说这也是不合理的,Form
就应该做Form的事情,显示东西和操作交互就行了,把数据的操作放在另一个地方,也就
是MVC模式,但这样显然不可能,至少还需要一个方法去通知数据的变化,于是就妥协的保
留了一两个类似RefreshData这样的方法,也被叫成MVP模式
一般而言这种实现方式还是不错的,这种方式下Form一般只持有一个对DataModel的引用,
然后拥有一个类似RefreshData这样的数据响应方法,而我也经常习惯于在构造器中要求传
入这样的DataModel,因为我看来这种情况下Form和Data就是一体,没有DataModel的Form
是没有意义的

P.S. WPF引入数据绑定后,DataContext之类概念后,实现变得漂亮很多~Form终于不用自
己去持有那个对DataModel的引用了
【 在 hustorochi (Mark Zhou) 的大作中提到: 】: 
: 我们在编写程序的时候,应该尽量减少组件之间的偶合性,对于 DialogResult,它依赖于
:  ModalDialog,如果程序显示的是一个 Modaless Dialog,那么 DialogResult 不产生任
: 何值,从而 UI 的改变导致了代码的改变。
: 
: 另一方面,我也不推荐通过构造函数对 UI 组件传递数据。构造函数是用来对其所描述的
: 类进行实例化的,而不是用来传递数据的;换句话说,构造函数应该干他应该干的事情。

--

    上善若水
    水利万物而不争
Hello you, Hello me, Hello World...
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·

 

 
 
发信人: joshuaG (G|想念变成一条线 在时间里面蔓延), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月11日16:31:08 星期三), 站内信件

我对自己的代码做Code Metrics分析的时候,糟糕的地方都是在Winform代码里头出现的

【 在 yayxcn (羊肉贩子): 贩卖羊肉和代码 (oh Yannic!) 的大作中提到: 】
: UI组件 和 数据 的绑定说到点上了。。。
: 我觉得这地方也不用完全追求分离
: 其实Winform里面UI组件和数据本来就是在一起的
: 比如xxxForm类里面经常有个类似RefreshData方法,从理论上来说这也是不合理的,Form
: 就应该做Form的事情,显示东西和操作交互就行了,把数据的操作放在另一个地方,也就
: 是MVC模式,但这样显然不可能,至少还需要一个方法去通知数据的变化,于是就妥协的保
: 留了一两个类似RefreshData这样的方法,也被叫成MVP模式
: 一般而言这种实现方式还是不错的,这种方式下Form一般只持有一个对DataModel的引用,
: 然后拥有一个类似RefreshData这样的数据响应方法,而我也经常习惯于在构造器中要求传
: 入这样的DataModel,因为我看来这种情况下Form和Data就是一体,没有DataModel的Form
: .................(以下省略)

--
            ┓·    ┓        ·             爱好者协会
★和平演变★┃┓┏┓┣┓╋┳┓┓┳┓┏┓  ┍┅━┅━┅━┅┗┻┗┫┛┗┗┛┗┻┛┗┗┫  ID:joshuaG
   通行证   ┗┛                ┗┛  
━━━━──┼────────────────┺┉编号:07
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·[FROM:Utopian Blue]

 

 
 
发信人: yayxcn (羊肉贩子): 贩卖羊肉和代码 (oh Yannic!), 信区: DotNet
标  题: Re: [求教]C#如何两窗口之间发送消息
发信站: 武汉白云黄鹤站 (2009年03月11日16:55:10 星期三), 站内信件

因为form的概念本身就可维护性不怎么样
属于20世纪90年代快速开发概念的遗留产物
iphone android 包括asp.net mvc都抛弃form概念
winform webform最后都没有成功

【 在 joshuaG (G|想念变成一条线 在时间里面蔓延) 的大作中提到: 】
: 我对自己的代码做Code Metrics分析的时候,糟糕的地方都是在Winform代码里头出现的
: 【 在 yayxcn (羊肉贩子): 贩卖羊肉和代码 (oh Yannic!) 的大作中提到: 】
: : UI组件 和 数据 的绑定说到点上了。。。
: : 我觉得这地方也不用完全追求分离
: : 其实Winform里面UI组件和数据本来就是在一起的
: : 比如xxxForm类里面经常有个类似RefreshData方法,从理论上来说这也是不合理的,Form

--

    上善若水
    水利万物而不争
Hello you, Hello me, Hello World...
※ 来源:·武汉白云黄鹤站 bbs.whnet.edu.cn·
posted @ 2009-04-25 12:44  InfantSorrow  阅读(4530)  评论(0编辑  收藏  举报