事件的使用及方法特点
事件(event)
观察1:this.btnCreateChildForm.Click += System.EventHandler(this.btnCreateChildForm_Click);
观察2:public event EventHandler Click;
观察3:public delegate void EventHandler(object sender, EventArgs e);
1. 事件的本质:事件就是对委托的进一步包装。
延时思考:买东西通常会有一个包装。(包装对实物起到保护作用)
程序优秀:(健壮性)代码规范、技术综合运用好(简化、好的技术点、扩展性...)-->不容易出问题。
2、事件
【1】在委托类型前面添加event就可以定义事件。
【2】事件必须使用+=或-=,不能直接=赋值。
【3】事件移除(也)不能使用null,只能使用-=方式。
3、事件参与者
【1】发送者(sender):也就是用来激发事件,通知所有的接受这接受消息。
private void btnSend_Click(object sender, EventArgs e)
{
//【5】激发事件
EventChildReceive(this.txtSendMsg.Text);
}
【2】接受者(Receiver):就是事件的处理者,在事件发送者触发事件后,自定执行的代码。
private void ReceiveMsg(string data)
{
this.txtContent.Text += data + "\r\n";
}
namespace thinger.EventApp
{
//【1】声明委托
public delegate void ReceiveDelegate(string msg);
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
}
//把子窗体对象放到容器中
private List<Form> formList = new List<Form>();
// public delegate void EventHandler(object sender, EventArgs e);
private void btnCreateChildForm_Click(object sender, EventArgs e)
{
for (int i = 1; i < 4; i++) //创建3个子窗体
{
FrmChild frm = new FrmChild(i);
frm.Show();
//【4】关联委托变量和方法
frm.EventChildReceive += ReceiveMsg;
//将当前窗体对象添加到集合
formList.Add(frm);
}
}
//【2】事件的接受者
private void ReceiveMsg(string data)
{
this.txtContent.Text += data + "\r\n";
}
//移除事件
private void btnClearEvent_Click(object sender, EventArgs e)
{
foreach (FrmChild item in formList)
{
//item.EventChildReceive = null;//这种方式不允许
item.EventChildReceive -= ReceiveMsg;//只能通过这种方式移除事件
}
}
}
}
namespace thinger.EventApp
{
public partial class FrmChild : Form
{
public FrmChild(int num)
{
InitializeComponent();
this.Text += $" [{num}]";
}
//【3】创建事件
public event ReceiveDelegate EventChildReceive;
private void btnSend_Click(object sender, EventArgs e)
{
//【5】激发事件
EventChildReceive(this.txtSendMsg.Text);
}
}
}
- 声明委托
- 声明方法原型 接收者/订阅者
- 创建事件 / 类似声明事件变量
- 事件订阅方法 +=
- 激发事件
4、事件和委托对比
第一、事件无法在“外面”赋值。比如“对象.事件=null”,会出现编译错误,而委托可以。
好处:避免用户对事件直接操作,比如Click事件,如果允许Click=null,会把底层代码清除。事件就可以起到保护作用。而委托相对“太开放”。
第二、event对象没有invoke()方法(了解)。