事件本身就是观察者模式的一个实现。
先总结一下事件的使用:
- 委托类型声明
- 定义发布者类,并声明事件
- 在发布者类中定义触发事件方法
- 定义订阅者类,并注册事件
- 在订阅者类中定义事件处理方法
针对事件,.Net Framework提供了一个标准模式,主要在winform中比较常见,区别就是不用自定义委托,使用EventHander委托,因此其步骤是:
- 定义发布者类,并声明事件
- 在发布者类中定义触发事件方法
- 定义订阅者类,并注册事件
- 在订阅者类中定义事件处理方法
上述步骤是在委托方法中不传参的情况,如果需要传递参数,则需要自定义EventHander中的EventArgs对象,并使用泛型委托EventHander,其步骤是:
- 定义类,继承自EventArgs,目的是为了加属性传参
- 定义发布者类: 事件的定义,使用自定义类的EventHander泛型委托
- 在发布者类中定义 触发事件的方法,在这个方法中填充需要传递的参数,给1中自定义类的属性赋值
- 定义订阅者类: 订阅事件
- 订阅者: 事件处理的方法,使用委托传过来的参数(继承自EventArgs类的属性)
使用事件实现winform窗体传值感觉比使用简单方法,在发布者类中维护订阅者类列表要简单一点;
而且后期扩展要更容易。
实例:本实例定义一个winform程序,有三个窗体,实现frmMain中的textbox更新内容,frmSub1和frmSub2中的textbox同样更新内容,以下是示例代码:
FrmMain的代码: namespace SendMessageWithEvent { /// <summary> /// 委托,事件处理程序的方法的参数和返回值必须要与该委托一致 /// </summary> /// <param name="message"></param> public delegate void MsgHander(string message); public partial class FrmMain : Form { public FrmMain() { InitializeComponent(); } /// <summary> /// 定义事件 /// </summary> public event MsgHander SendMsgEvent; private void txtMessage_TextChanged(object sender, EventArgs e) { string msg = txtMessage.Text; //触发事件 SendMsgEvent(msg); } } } FrmSub1的代码: namespace SendMessageWithEvent { public partial class FrmSub1 : Form { /// <summary> /// 当前窗体是否处于显示状态 /// </summary> private bool isShown = false; /// <summary> /// 用于关闭窗体时,移除事件监听 /// </summary> private FrmMain _frmMain; public FrmSub1(FrmMain frmMain) { _frmMain = frmMain; //注册事件处理程序 _frmMain.SendMsgEvent += ChangeMsg; InitializeComponent(); } /// <summary> /// 事件处理程序 /// </summary> /// <param name="message"></param> private void ChangeMsg(string message) { if (isShown==false) { this.Show(); isShown = true; } txtMessage.Text = "Sub1: "+ message; } /// <summary> /// 窗体关闭时,移除事件监听 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FrmSub1_FormClosing(object sender, FormClosingEventArgs e) { _frmMain.SendMsgEvent -= ChangeMsg; } } } namespace SendMessageWithEvent { static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); FrmMain frmMain = new FrmMain(); FrmSub1 frmSub1 = new FrmSub1(frmMain); FrmSub2 frmSub2 = new FrmSub2(frmMain); Application.Run(frmMain); } } }
完整源代码参考:https://gitee.com/Alexander360/ProDotnetDesignPatternFramework45
来源:https://www.cnblogs.com/AlexanderZhao/p/12190237.html