通过关键字event定义事件,定义的基础必须定义委托,否则无法定义事件,因此C#中的事件是一种用于处理特定事件的机制,机制原理之后通过反编译查看时再说
定义事件
1)添加用户控件,将其拖入窗体中,在用户控件中编写定义事件的代码(添加设置用户控件流程与昨天一样,不再赘述)与用户控件中按钮的三连击代码,最后生成此用户控件,在工具箱中就会显示自定义的用户控件
//与昨天代码几乎一样
//最大的不同是 定义委托时
//多了个event关键字
//因此变成了定义事件
using System;
using System.Drawing;
using System.Windows.Forms;
namespace _02定义事件
{
//1 定义一个无参数无返回值的委托类型
public delegate void TripleClickDelegate();
public partial class UCEventButton : UserControl
{
public UCEventButton()
{
InitializeComponent();
}
//2 定义事件,与委托相比只是多了一个event关键字
public event TripleClickDelegate TripleClick;
//3 使用一个用于计数的变量
int count = 0;
private void button1_Click(object sender, EventArgs e)
{
count++;
this.Parent.Text = count.ToString();
if (count >= 3)
{
//4 调用事件
if(TripleClick != null)
{
TripleClick();
count = 0;
this.Parent.Text = count.ToString();
}
}
}
}
}
2)从工具箱中将上面生成的用户控件拖入窗体中,在窗体的加载(Load)事件中为事件注册该事件的处理程序(就是给事件赋值方法名)
using System;
using System.Drawing;
using System.Windows.Forms;
namespace _02定义事件
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//TripleClick 前面图标会变成事件的 闪电 样式
//窗体中,此时不能再使用=赋值
//只能使用+=或-=赋值
//解决昨天示例中被使用=号覆盖的问题
//ucEventButton1.TripleClick = M1;
//应改为
ucEventButton1.TripleClick += M1;
}
private void M1()
{
Console.WriteLine("触发事件的处理程序1");
}
}
}
3)窗体中添加有关普通按钮,在单击事件中调用用户控件的事件冒充用户控件
private void button1_Click(object sender, EventArgs e)
{
//直接调用事件
//报错:只能出现在 += 或 -= 的左边
ucEventButton1.TripleClick();
//为其注册处理程序
//在button1_Click事件中不会执行M5()
//但在用户控件的三连击中会执行M5()
ucEventButton1.TripleClick += M5;
//解决了类外调用问题
//即只能由用户控件调用处理程序,
//其他冒充事件中只能累加注册处理程序,不能直接调用
}
private void M5()
{
MessageBox.Show("Test");
}
事件本质
反编译定义的事件 TripleClick ,查看其事件本质
事件本质:把定义的事件 public event TripleClickDelegate TripleClick;编译为三部分
1)编译为1个私有的委托变量TripleClick,其类型就是定义的委托类型TripleClickDelegate
2)编译为两个公有的方法(add添加/remove删除 处理程序)
类比属性:一个私有字段(类内部使用),两个公有方法(暴露给外部取值/赋值)