类或者对象可以通过事件向其它类或者对象通知发生相关的事情。发送(或引发)事件的类称为“发布者”,接收(或处理)事件的类称为“订阅者”。
事件的属性特征:
1.发行者确定何时引发事件;订户确定对事件做出何种响应。
2.一个事件可以拥有多个订户;订户可以处理来自多个发行者的多个事件。
3.没有订户的事件永远也不会引发。
4.事件通常表示用户的操作,例如单击按钮或者图形用户界面中的菜单栏选项。
5.当事件具有多个订户时,引发事件时会同步调用事件处理程序。
6. 在.NET Framework类库中,事件基于EventHandler
委托和EventArgs
基类(.NET Framework类库中的所有事件均基于EventHandler
委托)。
符合.NET准则的事件
定义如下:
public delegate void EventHandler(object sender, EventArgs e);
**注意:**在.NET Framework 2.0引入了泛型版本的委托EventHandler<TEventArgs>
。EventHandler
和泛型EventHandler<TEventArgs>
均为委托类型。
尽管定义的类中的事件可基于任何有效委托类型,甚至是返回值的委托。但一般还是建议使用EventHandler
,使事件基于.NET模式。
名称EventHandler
可能会造成一些混淆,因为它不会实际处理事件。其签名与委托定义匹配的方法或Lambda表达式事件处理程序,并将在引发事件时调用。
发布基于EventHandler
模式的事件
1.将自定义数据的类声明为对发布服务器和订阅者类均为可见的范围。然后添加所需成员以保留自定义事件数据。在下面的示例中,将返回一个简单的字符串。
internal class CustomEventArgs : EventArgs
{
public CustomEventArgs(string message)
{
this.Message = message;
}
public string Message { get; set; }
}
2.声明发布类中的委托(若使用的是EventHandler<TEventArgs>
泛型版本,请忽略此步骤)。命名通常指定为以EvengHandler
结尾的名称。第二个参数指定为自定义EventArgs
子类的类型。
public delegate void CustomEventHandler(object sender, CustomEventArgs args);
3.使用下列步骤之一来声明发布类中的事件。
如果没有自定义EventArgs
类,事件类型将为非泛型的EventHandler
委托。在C#中,不需要声明该委托,因为在创建C#项目时,已经包括在System命名的空间中。将下列代码添加到发布服务器类。
public event EventHandler RaiseCustomEvent;
如果使用非泛型版本EventHandler
,并且具有派生自EventArgs
的自定义类,请声明发布类中的事件,并将步骤2中的委托用作类型。
public event CustomEventHandler RaiseCustomEvent;
如果使用泛型版本,则无需自定义委托。只需在发布类中,将事件类型指定为EventHandler<CustomEventArgs>
,尖括号中替换为自定义的类型名称。
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
下例通过自定义EventArgs
类和EventHandler<TEventArgs>
作为事件类型演示上述的步骤。
public class UserCustomizeEvent
{
public UserCustomizeEvent()
{
var pub = new Publisher();
var Sub = new Subscriber("调用者1", pub);
var Sub_2 = new Subscriber("调用者2", pub);
//调用引发事件的方法
pub.DoSomething();
}
//事件订阅者
internal class Subscriber
{
private readonly string _id;
public Subscriber(string id, Publisher pub)
{
this._id = id;
pub.RaiseCustomEvent += HandleCustomEvent;
}
private void HandleCustomEvent(object sender, CustomEventArgs e)
{
Console.WriteLine($"{_id}接收到的消息为:{e.Message}");
}
}
//事件发布者
internal class Publisher
{
//声明事件使用EventHandler<T>
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
public Publisher()
{
}
public void DoSomething()
{
OnRaiseCustomeEvent(new CustomEventArgs("事件触发器开始触发,"));
}
protected virtual void OnRaiseCustomeEvent(CustomEventArgs e)
{
EventHandler<CustomEventArgs> raiseEvent = RaiseCustomEvent;
if(raiseEvent != null)
{
e.Message += $"触发的时间为:{DateTime.Now}";
raiseEvent(this, e);
}
}
}
//自定义事件类型,保留自定义事件数据
internal class CustomEventArgs : EventArgs
{
public CustomEventArgs(string message)
{
this.Message = message;
}
public string Message { get; set; }
}
}
总结
1.事件通过event
关键字修饰,且通过委托类型进行定义。
2.类或者对象通过事件向其它类或者对象通知发生相关的事情。
3.发生(或引发)事件的类称为“发布者”;接收(或处理)事件的类称为“订阅者”。
4.事件的六大属性特征。
5.标准的.NET委托有EventHandler
和泛型类EventHandler<TEventArgs>
(.NET Framework 2.0引入),它们均为委托类型。
6.在.NET Framework中,事件基于EventHandler
委托和EventArgs
基类。
7.在使用泛型类EventHandler<TEventArgs>
作为事件类型定义时,无需声明委托类型;否则,需要对委托类型进行声明,并使用声明的委托类型进行声明事件。