• 全部
...

WinForm窗体之间参数传递(委托加事件观察者模式实现)

mytimes_walker 2010-01-12 12:57:57
偶有闲时,看到了有人问起WinForm直接窗体参数的传递。回想起之前的牛X老师所教的方法,特写一小例子,共享之。
所谓观察者,就好比警察抓小偷时放出的眼线,眼线观察小偷,一有行动,立刻反应给警察。
现有FrmMain(警察),FrmChild1,FrmChild2(姑且当作两个小偷吧),一个定义委托和事件的类MiddleModule,它就是观察者。
且看代码:

  1. MiddleModule:

  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;

  5. namespace Observer
  6. {
  7. /// <summary>
  8. /// 定义发布消息的委托
  9. /// </summary>
  10. /// <param name="sender">发布者</param>
  11. /// <param name="msg">消息</param>
  12. public delegate void Send(object sender, object msg);
  13. /// <summary>
  14. /// 观察者的中间模块组建
  15. /// </summary>
  16. public class MiddleModule
  17. {
  18. /// <summary>
  19. ///消息发布的事件
  20. /// </summary>
  21. public static event Send eventSend;

  22. public static void SendMessage(object sender, object msg)
  23. {
  24. if (eventSend != null)
  25. {
  26. eventSend(sender, msg);
  27. }
  28. }
  29. }
  30. }

警察:


  1. namespace WinObserver
  2. {
  3. public partial class FrmMain : Form
  4. {
  5. /// <summary>
  6. /// 构造方法,在构造主窗体的时候就订阅来自FrmChild1的消息
  7. /// </summary>
  8. public FrmMain()
  9. {
  10. InitializeComponent();
  11. MiddleModule.eventSend += new Send(MiddleModule_eventSend);
  12. }

  13. /// <summary>
  14. /// 接收FrmChild1的回传数据
  15. /// </summary>
  16. /// <param name="sender"></param>
  17. /// <param name="msg"></param>
  18. void MiddleModule_eventSend(object sender, object msg)
  19. {
  20. FrmChild1 frmChild1 = sender as FrmChild1;
  21. if (null != frmChild1)
  22. {
  23. this.lblMsg.Text = "FrmChild1的回传数据:"+msg.ToString();
  24. }
  25. }

  26. private void btnShow1_Click(object sender, EventArgs e)
  27. {
  28. FrmChild1 frmChild1 = FrmChild1.CreateInstance();
  29. frmChild1.Show();
  30. }

  31. private void btnShow2_Click(object sender, EventArgs e)
  32. {
  33. FrmChild2 frmChild2 = FrmChild2.CreateInstance();
  34. frmChild2.Show();
  35. }

  36. private void btnSend_Click(object sender, EventArgs e)
  37. {
  38. //由Observer模块传递数据
  39. if (String.IsNullOrEmpty(this.txtMsg.Text))
  40. {
  41. MiddleModule.SendMessage(this, String.Empty);
  42. }
  43. else
  44. {
  45. MiddleModule.SendMessage(this, this.txtMsg.Text);
  46. }
  47. }
  48. }
  49. }

小偷1:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using Observer;

  10. namespace WinObserver
  11. {
  12. public partial class FrmChild1 : Form
  13. {
  14. private static FrmChild1 frmChild1 = null;

  15. private FrmChild1()
  16. {
  17. InitializeComponent();
  18. MiddleModule.eventSend += new Send(MiddleModule_eventSend);
  19. }

  20. void MiddleModule_eventSend(object sender, object msg)
  21. {
  22. FrmMain frmMain = sender as FrmMain;
  23. if (null != frmMain)
  24. {
  25. this.lblMsg.Text = msg.ToString();
  26. }
  27. }

  28. public static FrmChild1 CreateInstance()
  29. {
  30. if (null == frmChild1)
  31. {
  32. frmChild1 = new FrmChild1();
  33. }
  34. return frmChild1;
  35. }

  36. private void btnSendBack_Click(object sender, EventArgs e)
  37. {
  38. //由Observer模块传递数据
  39. if (String.IsNullOrEmpty(this.txtMsg.Text))
  40. {
  41. MiddleModule.SendMessage(this, String.Empty);
  42. }
  43. else
  44. {
  45. MiddleModule.SendMessage(this, this.txtMsg.Text);
  46. }
  47. }
  48. }
  49. }

小偷2:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using Observer;

  10. namespace WinObserver
  11. {
  12. public partial class FrmChild2 : Form
  13. {
  14. private static FrmChild2 frmChild2 = null;

  15. /// <summary>
  16. /// 接收来自FrmMain传递过来的数据
  17. /// </summary>
  18. private FrmChild2()
  19. {
  20. InitializeComponent();
  21. MiddleModule.eventSend += new Send(MiddleModule_eventSend);
  22. }

  23. void MiddleModule_eventSend(object sender, object msg)
  24. {
  25. FrmMain frmMain = sender as FrmMain;
  26. if (null != frmMain)
  27. {
  28. this.lblMsg.Text = msg.ToString();
  29. }
  30. }

  31. public static FrmChild2 CreateInstance()
  32. {
  33. if (null == frmChild2)
  34. {
  35. frmChild2 = new FrmChild2();
  36. }
  37. return frmChild2;
  38. }
  39. }
  40. }

源代码,大家可以到http://download.csdn.net/source/1986872下载。
...全文
给本帖投票
3513 45 打赏 收藏 转发到动态 举报
写回复
用AI写文章
45 条回复
切换为时间正序
请发表友善的回复…
发表回复
sniper_xutao 2012-09-24
  • 打赏
  • 举报
回复
大家都说的很不错。
dxshenhua 2011-01-21
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 yulinlover 的回复:]
设计模式是必须要学的,对于那些对设计模式不屑一顾的人来说,无外乎是2类:
1、他已经很熟悉了各种设计模式,更是了解了面向对象的本质,在特定的问题上都已经可以自由发挥和变通了。
2、另一类就是“吃不到葡萄说葡萄酸的”那类人了。

所以我建议代码写的不怎么样的?或者说是平时在工作中维护产品的时候经常要去改旧的已有的组件的那些同志,我就建议你好好去学习下设计模式,对于这一块的资料,我相信Head……
[/Quote]
中国人都有一颗计谋的心,很多人实际的开发书籍不看,实际的项目没有做过,就花很多时间看这种书,到时候夸夸其谈,何其少也。况且,真正用得上设计模式的的软件,在中国,你一辈子可能都没资格做。不要告诉我做个国内什么网游发发网络包,做个什么ERP读写读写数据库,用的着多少设计模式。退一步说,这种东西,就是学院派的东西,要不然大家都学编程的实际活,不都落了下层了吗,学院派讲究个理论,讲究个台面的东西,你代码拿出来,领导看不懂,拿这个出来,不是个文盲都能说几句。做个什么经理,总监了,不干编码了,干嘛,不就嘴巴动动嘛,说什么呢,自己编的名词不够权威,那好,已经有那些吃饱了没事干的教授,专家,帮你想好了一套名词,你的任务就是吹吧。没有扎实的编程实践,这些东西就是上台演讲用的讲词,有了扎实的编程实践,这些东西就留给那些愿意被忽悠的人吧。
shoucalwenxia 2010-09-07
  • 打赏
  • 举报
回复
哦,原来如此
visionsky1986 2010-07-29
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 yulinlover 的回复:]

设计模式是必须要学的,对于那些对设计模式不屑一顾的人来说,无外乎是2类:
1、他已经很熟悉了各种设计模式,更是了解了面向对象的本质,在特定的问题上都已经可以自由发挥和变通了。
2、另一类就是“吃不到葡萄说葡萄酸的”那类人了。

所以我建议代码写的不怎么样的?或者说是平时在工作中维护产品的时候经常要去改旧的已有的组件的那些同志,我就建议你好好去学习下设计模式,对于这一块的资料,我相信Hea……
[/Quote]

精辟~~~~~~~~
yinrongg 2010-01-14
  • 打赏
  • 举报
回复
不错,收藏
antony1029 2010-01-14
  • 打赏
  • 举报
回复
UP
cszg_zjy 2010-01-14
  • 打赏
  • 举报
回复
学习 帮顶
acqy 2010-01-13
  • 打赏
  • 举报
回复
学习是应该的,也是必须的,至少能够先让你在大脑里有个印象,遇到什么问题可以用什么办法解决,以后在设计中遇到类似的问题,就可以套用现成的解决方案,然后再根据自己的实际情况加以修改。
yuanhuiqiao 2010-01-13
  • 打赏
  • 举报
回复
学习一下模式还是应该的吗
mytimes_walker 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 xinsiyu2008 的回复:]
C# codepublicclass MiddleModule
{///<summary>///消息发布的事件///</summary>publicstaticevent Send eventSend;publicstaticvoid SendMessage(object sender,object msg)
{if (eventSend!=null)
{
eventSend(sender, msg);
}
}
}
这个类在每一个子窗口中这样加托管MiddleModule.eventSend += new Send(MiddleModule_eventSend);
是不是每次都生成一个新的实例啊?
还有每个子窗口中有这样一句C# codeprivatestatic FrmChild1 frmChild1=null;会导致子窗口关闭后,再按主窗口的showchild时会报错。不明白为什么要储存这个子变量......d大家继续讨论啊~!
[/Quote]
因为我用了单例模式。
mytimes_walker 2010-01-13
  • 打赏
  • 举报
回复
修改FrmChild1和FrmChild2的CreateInstance方法。

public static FrmChild1 CreateInstance()
{
if (null == frmChild1 || frmChild1.IsDisposed)
{
frmChild1 = new FrmChild1();
}
return frmChild1;
}
public static FrmChild2 CreateInstance()
{
if (null == frmChild2 || frmChild2.IsDisposed)
{
frmChild2 = new FrmChild2();
}
return frmChild2;
}
Justin-Liu 2010-01-13
  • 打赏
  • 举报
回复
了解一下
yulinlover 2010-01-13
  • 打赏
  • 举报
回复
设计模式是必须要学的,对于那些对设计模式不屑一顾的人来说,无外乎是2类:
1、他已经很熟悉了各种设计模式,更是了解了面向对象的本质,在特定的问题上都已经可以自由发挥和变通了。
2、另一类就是“吃不到葡萄说葡萄酸的”那类人了。

所以我建议代码写的不怎么样的?或者说是平时在工作中维护产品的时候经常要去改旧的已有的组件的那些同志,我就建议你好好去学习下设计模式,对于这一块的资料,我相信HeadFirst一书应该算是不错的了,他不仅阐述了重要的常用的几种模式,更是把面向对象编程中的思想给提炼了一下。所以很值得去学习。

还有一点就是:如果你新到一个公司,不要自以为在架构方面的认识还算不错就去对公司的产品架构指指点点,这样只能说明你还嫩,因为有的产品可能是N年前的东西,你用现在的软件工程思想去看,那自然是落后的,所以在你提出XXXX架构不合理的时候,希望你已经把重构过的架构拿出来,那样会比你在那乱指点来的有说服力。并且可以很快在你的team里奠定你的地位。所以送给眼高手低的同志一句话:“少说多做”
acqy 2010-01-13
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 sp1234 的回复:]
我不反对学习设计模式,但是玩过了也就可以了,直截了当地针对应用来设计软件吧,设计软件时忘记设计模式而只是记起面向对象设计的原则,你能写出很好的堪称一般人的设计模式的软件设计来。
[/Quote]

再一次验证了我以前的一些想法,我以前也热衷于模式,直到有一次我自己用某种方法解决了某种问题后,我才发现,原来我的解决方案早已被别人定义成了模式后,我才恍然大悟,原来模式仅仅是种参考,在设计和开发中你仍然要根据实际情况来确定你的解决方案。
heguodong 2010-01-13
  • 打赏
  • 举报
回复
设计模式就是一些经过经过多年验证过了的,解决特定问题确实有效的方法,好东西
在中国还远远达不到过度使用,而正是其反面,还用的很不够
没仔细看上个10编8编,不好好想想每个模式后附带的思考问题,你别说你设计过度了,我不信,你就还没真正理解,怎么说得上过度.
很多人机械地套啊凑啊,就象学了面向对象,感觉什么都可以继承一样,这才是悲哀
7777766 2010-01-13
  • 打赏
  • 举报
回复
又一次看又一次受教
mytimes_walker 2010-01-12
  • 打赏
  • 举报
回复
我的失误,忘了Dispose了。
csdnfan 2010-01-12
  • 打赏
  • 举报
回复
public class MiddleModule
{
/// <summary>
///消息发布的事件
/// </summary>
public static event Send eventSend;

public static void SendMessage(object sender, object msg)
{
if (eventSend != null)
{
eventSend(sender, msg);
}
}
}

这个类在每一个子窗口中这样加托管MiddleModule.eventSend += new Send(MiddleModule_eventSend);
是不是每次都生成一个新的实例啊?
还有每个子窗口中有这样一句
private static FrmChild1 frmChild1 = null;
会导致子窗口关闭后,再按主窗口的showchild时会报错。不明白为什么要储存这个子变量......d大家继续讨论啊~!
xinnian_123 2010-01-12
  • 打赏
  • 举报
回复
顶!!!!!!!!!!
zhsleep 2010-01-12
  • 打赏
  • 举报
回复
学些中,不错!!
加载更多回复(22)

111,080

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧

手机看
关注公众号

关注公众号

客服 返回
顶部