WinForm窗体之间参数传递(委托加事件观察者模式实现)
偶有闲时,看到了有人问起WinForm直接窗体参数的传递。回想起之前的牛X老师所教的方法,特写一小例子,共享之。
所谓观察者,就好比警察抓小偷时放出的眼线,眼线观察小偷,一有行动,立刻反应给警察。
现有FrmMain(警察),FrmChild1,FrmChild2(姑且当作两个小偷吧),一个定义委托和事件的类MiddleModule,它就是观察者。
且看代码:
MiddleModule:using System;using System.Collections.Generic;using System.Text;namespace Observer{ /// <summary> /// 定义发布消息的委托 /// </summary> /// <param name="sender">发布者</param> /// <param name="msg">消息</param> public delegate void Send(object sender, object msg); /// <summary> /// 观察者的中间模块组建 /// </summary> public class MiddleModule { /// <summary> ///消息发布的事件 /// </summary> public static event Send eventSend; public static void SendMessage(object sender, object msg) { if (eventSend != null) { eventSend(sender, msg); } } }}
namespace WinObserver
{
public partial class FrmMain : Form
{
/// <summary>
/// 构造方法,在构造主窗体的时候就订阅来自FrmChild1的消息
/// </summary>
public FrmMain()
{
InitializeComponent();
MiddleModule.eventSend += new Send(MiddleModule_eventSend);
}
/// <summary>
/// 接收FrmChild1的回传数据
/// </summary>
/// <param name="sender"> </param>
/// <param name="msg"> </param>
void MiddleModule_eventSend(object sender, object msg)
{
FrmChild1 frmChild1 = sender as FrmChild1;
if (null != frmChild1)
{
this.lblMsg.Text = "FrmChild1的回传数据:"+msg.ToString();
}
}
private void btnShow1_Click(object sender, EventArgs e)
{
FrmChild1 frmChild1 = FrmChild1.CreateInstance();
frmChild1.Show();
}
private void btnShow2_Click(object sender, EventArgs e)
{
FrmChild2 frmChild2 = FrmChild2.CreateInstance();
frmChild2.Show();
}
private void btnSend_Click(object sender, EventArgs e)
{
//由Observer模块传递数据
if (String.IsNullOrEmpty(this.txtMsg.Text))
{
MiddleModule.SendMessage(this, String.Empty);
}
else
{
MiddleModule.SendMessage(this, this.txtMsg.Text);
}
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Observer;
namespace WinObserver
{
public partial class FrmChild1 : Form
{
private static FrmChild1 frmChild1 = null;
private FrmChild1()
{
InitializeComponent();
MiddleModule.eventSend += new Send(MiddleModule_eventSend);
}
void MiddleModule_eventSend(object sender, object msg)
{
FrmMain frmMain = sender as FrmMain;
if (null != frmMain)
{
this.lblMsg.Text = msg.ToString();
}
}
public static FrmChild1 CreateInstance()
{
if (null == frmChild1)
{
frmChild1 = new FrmChild1();
}
return frmChild1;
}
private void btnSendBack_Click(object sender, EventArgs e)
{
//由Observer模块传递数据
if (String.IsNullOrEmpty(this.txtMsg.Text))
{
MiddleModule.SendMessage(this, String.Empty);
}
else
{
MiddleModule.SendMessage(this, this.txtMsg.Text);
}
}
}
}
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using Observer;namespace WinObserver{ public partial class FrmChild2 : Form { private static FrmChild2 frmChild2 = null; /// <summary> /// 接收来自FrmMain传递过来的数据 /// </summary> private FrmChild2() { InitializeComponent(); MiddleModule.eventSend += new Send(MiddleModule_eventSend); } void MiddleModule_eventSend(object sender, object msg) { FrmMain frmMain = sender as FrmMain; if (null != frmMain) { this.lblMsg.Text = msg.ToString(); } } public static FrmChild2 CreateInstance() { if (null == frmChild2) { frmChild2 = new FrmChild2(); } return frmChild2; } }}
[解决办法]
不错!sf
[解决办法]
值得提倡!
[解决办法]
顶
[解决办法]
支持
[解决办法]
Form之间的参数传递方式有很多种,我也提倡使用事件来解决问题,这样可以解耦两个form之间的关联。换句话说,一个form可以选择订阅另一个form的事件,也可以选择不订阅,如果订阅,那么事件的发布方作了改动,事件的订阅方就被通知到,于是可以选择性地采取相应措施。
[解决办法]
收藏,学习
[解决办法]
原来这是分享代码啊,我还以为是问问题呢,不过我就不看了,自认为委托掌握的不错。
[解决办法]
好东西要顶 并且收藏
[解决办法]
.net架构中的事件概念根本不是什么观察者模式。模式是害人的,繁琐的,以繁琐为美的。.net中的事件如果用“警察与小偷的比喻”就会本末倒置。
硬要定义一个 MiddleModule 类,这就是以繁琐为美的典型例子。实际开发时,只要小偷类用一句话
public event EventHandler<EventArgs> Hi;
这就干净利落地定义了事件机制。反倒是那些拼命想用模式的人,用什么模式来偷换.net的事件机制,繁琐封装它的形式而不讲求逻辑简洁实用。
[解决办法]
学习了
[解决办法]
.net给我们提供了一些具体实用的编程技术(例如事件就是在1995年前vb广泛使用的机制),至于不同的编程语言、编译器、操作系统怎样支持它则可能实现机制完全不一样。因此,事件是一种设计思想,而所谓观察者模式只是底层实现方式之一。
这些.net技术,以及.net framework中各种框架,随便研究一部分你就会发现比设计模式丰富十倍的内容。
[解决办法]
如果在主窗体的构造函数中这样定义:Frm_Main()
{
m_PicCha = new PictureCharacterTable(m_dbConn);//图片窗体
m_frmProperty = new Frm_Property(m_dbConn, m_PicCha, m_picShow);// 属性窗体
m_fileshow = new Frm_FileShowing(m_frmProperty, m_picShow);//文件显示窗体
m_folder = new Frm_Folder(m_fileshow, m_dbConn, m_frmProperty, m_PicCha);//文件夹窗 体
}
有何不好?
[解决办法]
我不反对学习设计模式,但是玩过了也就可以了,直截了当地针对应用来设计软件吧,设计软件时忘记设计模式而只是记起面向对象设计的原则,你能写出很好的堪称一般人的设计模式的软件设计来。
[解决办法]
public class MiddleModule { /// <summary> ///消息发布的事件 /// </summary> public static event Send eventSend; public static void SendMessage(object sender, object msg) { if (eventSend != null) { eventSend(sender, msg); } } }
[解决办法]