Focus 事件
大多数项目都是非线性的,这表现在:
在桌面程序中你可能不得不等待用户单击一个按钮或者压下一个键,然后才能相应一个事件。
在服务程序中,你可能要等待一个网络请求的出现。在.NET Framework 中这些功能都是由事件提供的。
什么是事件呢?
事件是 一个对象发送的 一个用来标识某种行为发生的 消息。
这种事件可能是由用户交互引起的,比如说鼠标单击,或者是被某些逻辑代码监控的。
发出消息的对象我们称之为事件的发送者(event sender)。
捕获这个事件并进行响应的我们叫它事件的接收者(event receiver)。
在事件成员的交流过程中,事件发送类对谁将接收和处理它发出的事件是未知的。在他们之间所需要的就是一种中间载体。
在.NET Framework中定义了一种特殊的类型 委托(Delegate),用它来提供一个方法指针的功能。
什么是委托?
委托是一个能存储一个方法地址的类。它不同于别的类,一个委托类只有一个签名,并且它只存储符合它的签名的方法。
委托就相当于一个类型安全的指针或者回调。
当然委托还有别的用处,现在只讨论它在事件处理中的应用。
委托的定义,只需定义一个委托类。
委托的定义只提供委托的签名,而其实现则是由通用语言运行时来提供。
比如一个事件委托的定义如下:
public delegate void AlarmEventHandler(object sender, EventArgs e);
标准的事件委托签名是定义一个方法它没有返回值,并且它的第一个参数是Object类型的指向发生时间的一个对象实例。
它的第二个参数是继承自EventArgs类,用来存放事件相关参数的类。如果事件没有相关的参数数据,那么第二个参数就是一个简单的EventArgs对象实例。
否则,第二个参数就是一个从EventAgrs继承的自定义类,以提供存储事件相关参数的字段和属性。
EventHandler 只是一个预定义的委托,它仅仅表示一个事件的处理方法,并且不生成数据。
如果我们的事件生成数据,那我们必须提供我们自己定义的时间数据类型并且创建一个第二个参数为我们定义的数据类型的委托。
或者用泛型EventHandler委托类,把我们自定义的事件参数类作为泛型指定参数类型。
要关联一个事件它的处理方法,需要添加一个委托实例给事件,这样只要事件发生,事件处理程序就会被调用,除非你把这个委托从事件中移除。
如何响应一个事件?
要响应一个事件我们需要做两件事情:
1.创建一个方法来响应事件。 这个方法必须遵循委托定义的方法签名。一般来说,这就意味着它的返回值必须是void 并且接收两个参数:一个Object和一个EventArgs(或者其子类)。
如:
private void button1_Click(object sender,EventArgs e)
{
//方法体
}
2.在事件处理器中指明那个方法将接收事件并处理。
this.button1.Click += new System.EventHandler(this.button1_Click);
这样当事件发生时,响应的处理方法就会被执行了。
怎样发出一个事件?
发出一个事件我们最少要做三件事情:
1.创建一个委托
如:
public delegate void MyEventHandler(object sender,EventArgs e);
2.创建一个事件成员
如:
public event MyEventHandler MyEvent;
3.当我们需要触发事件时在一个方法内部去调用委托。
如:
MyEventHanlder handler = MyEvent;
EventArgs e = new EventArgs();
if(handler!=null)
{
handler(this,e);//调用委托
}
另外,如果我们需要给事件传入参数,则我们可以定义继承自EventArgs的自定义类,作为参数传递。