C#事件
前言
C#委托和事件一直是令初学者十分费解的内容,近期工作中再次碰到事件,翻阅观看一些资料和视频终于将工作中遇到的问题解决.在此为自己做个梳理小结
事件可以用来做什么?
可用于不同窗体之间传递消息或者数据
事件的声明
在声明一个事件之前,我们需要弄清楚事件模型的五个组成部分
事件模型的五个组成部分
- 事件发布者
- 事件订阅者
- 事件成员
- 事件订阅
- 事件处理器
C#Winform不同窗体间传递消息小例子
本例子实现的功能:
在主窗体的文本框中输入好待发送的内容然后单击主窗体的发送消息按钮,会弹出子窗体并显示从主窗体发送过来的内容。
事件的完整声明
主窗体的代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace EventExample
{
//自定义一个委托类型
public delegate void SendMessageEventHandler(string message);
public partial class Frm_Main : Form
{
//自定义一个委托类型字段
private SendMessageEventHandler SendMessageHandler;
//自定义一个事件
public event SendMessageEventHandler SendMessage
{
add { this.SendMessageHandler += value; }
remove { this.SendMessageHandler -= value; }
}
public Frm_Main()
{
InitializeComponent();
}
//1 事件发布者
private void btn_sendmessage_Click(object sender, EventArgs e)
{
//2 事件订阅者
Frm_Child child = new Frm_Child();
child.Show();
//3.事件成员 5.+=事件订阅
SendMessage += child.ShowMessage;
//触发事件
SendMessageHandler.Invoke(textBox1.Text);
}
}
}
子窗体的代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace EventExample
{
public partial class Frm_Child : Form
{
public Frm_Child()
{
InitializeComponent();
}
/// <summary>
/// 4.事件处理器
/// </summary>
/// <param name="message"></param>
public void ShowMessage(string message)
{
textBox1.Text = message;
}
}
}
事件的简略声明
主窗体的代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace EventExample
{
//自定义一个委托类型
public delegate void SendMessageEventHandler(string message);
public partial class Frm_Main : Form
{
//自定义一个事件成员
public event SendMessageEventHandler SendMessage;
public Frm_Main()
{
InitializeComponent();
}
//1 事件发布者
private void btn_sendmessage_Click(object sender, EventArgs e)
{
//2 事件订阅者
Frm_Child child = new Frm_Child();
child.Show();
//3.事件成员 5.+=事件订阅
SendMessage += child.ShowMessage;
//触发事件
SendMessage.Invoke(textBox1.Text);
}
}
}
子窗体的代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace EventExample
{
public partial class Frm_Child : Form
{
public Frm_Child()
{
InitializeComponent();
}
/// <summary>
/// 4.事件处理器
/// </summary>
/// <param name="message"></param>
public void ShowMessage(string message)
{
textBox1.Text = message;
}
}
}
总结
C#委托和事件最容易让人混淆的应该就是委托类型和委托类型字段这两个概念了。
注:声明委托类型(与类同级)≠ 声明委托类型字段(在类内部)。
在编写自定义事件时,抓住事件的五大模型;既谁是事件发布者,谁是事件的订阅者……
一般用法步骤:
识别出事件发布者–》判断出需要传递什么类型数据–》确定定义什么样的委托类型–》定义对应事件–》连接发布者和订阅者(可能有多个)–》触发事件–》执行事件处理器
结合工作对事件的理解
委托和事件,都是向用户(可以理解为其它未知地方)提供一个开放接口,将数据(或消息)推送到用户那里,只要用户订阅了,就会收到这个推送数据(或消息),推送数据(或消息)并不知道哪些用户会用到,但他知道订阅者,只推送给订阅者(可以多个订阅)。
比如:一个接收网络通信的数据,接收到数据解析后需要发布出去,可能会有界面显示用户要这个数据,一个存储用户要用到(将数据存储到文件或数据库),接收网络通信处理那里并不知道哪些用户要用到,他就申明一个委托或事件,然后界面显示用户和存储用户会订阅这个委托,当有数据收到时,会实时推送给订阅者用户,可以起到实时随机的处理(动态的)