一、什么是事件
事件涉及两类角色——事件发布者和事件订阅者
事件发布者:是指触发事件的对象,发布消息。
事件订阅者:是指捕获事件并作出相应处理。
二、使用事件
我们先来查看一个完整的使用事件示例:
示例一:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Example_event
{
public class Friend
{
public string Name;
public Friend( string name )
{
Name = name;
}
//事件处理函数,该函数需要符合DinnerHandler委托的定义
public void SendMessage( string message )
{
Console.WriteLine( message );
Console.WriteLine( this.Name + "收到了,准时参加饭局!" );
}
}
public class Dinner
{
//自定义委托
public delegate void DinnerHandler( string msg );
//使用自定义委托类型定义事件,事件名为DinnerEvent
public event DinnerHandler DinnerEvent;
//发出事件
public void OnDinnerComing( string msg )
{
//判断是否绑定了事件处理方法
if( null != DinnerEvent )
{
//触发事件
DinnerEvent( msg );
}
}
static void Main( string[ ] args )
{
Dinner dinner = new Dinner( );
//实例化朋友对象
Friend friend1 = new Friend( "张三" );
Friend friend2 = new Friend( "李四" );
//使用+=来订阅事件,事件绑定
dinner.DinnerEvent += new DinnerHandler( friend1.SendMessage );
//发出通知,此时只有订阅了事件的对象才能收到通知
dinner.OnDinnerComing( "朋友们,过来我家吃饭啦!" );
Console.ReadKey( );
}
}
}
运行结果:
事件订阅及使用的基本步骤:
1.定义事件
与定义类成员类似,仅需包含一个event关键字即可
其中委托类型可以是自定义委托,也可以是.NET类库中预定义的委托类型EventHandler
//自定义委托
public delegate void DinnerHandler( string msg );
//使用自定义委托类型定义事件,事件名为DinnerEvent
public event DinnerHandler DinnerEvent;
2.添加事件处理函数
注意:事件处理函数的定义需要与委托的定义保持一致,即其参数个数、参数类型和返回类型等需要与委托相同。
//事件处理函数,该函数需要符合DinnerHandler委托的定义
public void SendMessage( string message )
{
Console.WriteLine( message );
Console.WriteLine( this.Name + "收到了,准时参加饭局!" );
}
3. 事件绑定/取消
使用"+="运算符来订阅事件,使用"-="运算符来取消事件
//使用+=来订阅事件,事件绑定
dinner.DinnerEvent += new DinnerHandler( friend1.SendMessage );
4.事件触发
//发出事件
public void OnDinnerComing( string msg )
{
//判断是否绑定了事件处理方法
if( null != DinnerEvent )
{
//触发事件
DinnerEvent( msg );
}
}
//发出通知,此时只有订阅了事件的对象才能收到通知
dinner.OnDinnerComing( "朋友们,过来我家吃饭啦!" );
上述我们使用的是自定义委托类型来定义事件,同样,我们也可以使用.NET类库中预定义的委托类型EventHandler来定义事件,如下所示:
示例二:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Example_event
{
public class Friend
{
public string Name;
public Friend( string name )
{
Name = name;
}
//事件处理函数,该函数需要符合EventHandler委托的定义
public void SendMessage( object sender, EventArgs e )
{
//Console.WriteLine( message );
Console.WriteLine( this.Name + "收到了,准时参加饭局!" );
}
}
public class Dinner
{
//访问修饰符 event 委托类型 事件名
public event EventHandler DinnerEvent;
//自定义委托
//public delegate void DinnerHandler( string msg);
//使用自定义委托类型定义事件,事件名为DinnerEvent
//public event DinnerHandler DinnerEvent;
//发出事件
public void OnDinnerComing( string msg )
{
//判断是否绑定了事件处理方法
if( null != DinnerEvent )
{
Console.WriteLine( msg );
//触发事件
DinnerEvent( this, new EventArgs( ) );
}
}
static void Main( string[ ] args )
{
Dinner dinner = new Dinner( );
//实例化朋友对象
Friend friend1 = new Friend( "张三" );
Friend friend2 = new Friend( "李四" );
//使用+=来订阅事件,事件绑定
dinner.DinnerEvent += new EventHandler( friend1.SendMessage );
//发出通知,此时只有订阅了事件的对象才能收到通知
dinner.OnDinnerComing( "朋友们,过来我家吃饭啦!" );
Console.ReadKey( );
}
}
}
示例二与示例一的区别:
两者事件定义的委托不同,导致事件处理函数也存在不同。示例二的事件委托类型为EventHandler,我们可以通过F12查看其定义:
委托定义如上,这样,相应的我们事件处理函数应该与其保持一致
//事件处理函数,该函数需要符合EventHandler委托的定义
public void SendMessage( object sender, EventArgs e )
{
//Console.WriteLine( message );
Console.WriteLine( this.Name + "收到了,准时参加饭局!" );
}
三、扩展EventArgs类
上述示例二,我们发现EventHandler只用于处理不包含事件数据的事件。如果我们想要在由这种方式定义的事件中包含事件数据,则可以通过派生EventArgs类来实现。下面通过扩展EventArgs类来使事件参数e带有事件数据,具体实现代码如下:
示例三:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Example_event
{
public class Friend
{
public string Name;
public Friend( string name )
{
Name = name;
}
//事件处理函数,该函数需要符合EventHandler委托的定义
public void SendMessage( object sender, DinnerEventArgs e )
{
Console.WriteLine( e.Message );
Console.WriteLine( this.Name + "收到了,准时参加饭局!" );
}
}
//自定义事件类,并使其带有事件数据
public class DinnerEventArgs : EventArgs
{
public string Message;
public DinnerEventArgs( string msg )
{
Message = msg;
}
}
public class Dinner
{
//采用.NET自带的EventHandler委托(示例二)
//访问修饰符 event 委托类型 事件名
//public event EventHandler DinnerEvent;
//自定义委托 (示例一)
//public delegate void DinnerHandler( string msg);
//使用自定义委托类型定义事件,事件名为DinnerEvent
//public event DinnerHandler DinnerEvent;
//扩展EventArgs类(示例三)
//自定义委托类型,委托包含两个参数
public delegate void DinnerHandler( object sender, DinnerEventArgs e );
//定义事件
public event DinnerHandler DinnerEvent;
//发出事件
public void OnDinnerComing( string msg )
{
//判断是否绑定了事件处理方法
if( null != DinnerEvent )
{
//Console.WriteLine( msg );
//触发事件
DinnerEvent( this, new DinnerEventArgs( msg ) );
}
}
static void Main( string[ ] args )
{
Dinner dinner = new Dinner( );
//实例化朋友对象
Friend friend1 = new Friend( "张三" );
Friend friend2 = new Friend( "李四" );
//使用+=来订阅事件,事件绑定
dinner.DinnerEvent += new DinnerHandler( friend1.SendMessage );
//发出通知,此时只有订阅了事件的对象才能收到通知
dinner.OnDinnerComing( "朋友们,过来我家吃饭啦!" );
Console.ReadKey( );
}
}
}
当然,我们还可以使用EventHandler<>方式来对EventArgs进行扩展
示例四:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Example_event
{
public class Friend
{
public string Name;
public Friend( string name )
{
Name = name;
}
//事件处理函数,该函数需要符合EventHandler委托的定义
public void SendMessage( object sender, DinnerEventArgs e )
{
Console.WriteLine( e.Message );
Console.WriteLine( this.Name + "收到了,准时参加饭局!" );
}
}
//自定义事件类,并使其带有事件数据
public class DinnerEventArgs : EventArgs
{
public string Message;
public DinnerEventArgs( string msg )
{
Message = msg;
}
}
public class Dinner
{
//采用.NET自带的EventHandler委托(示例二)
//访问修饰符 event 委托类型 事件名
//public event EventHandler DinnerEvent;
//自定义委托 (示例一)
//public delegate void DinnerHandler( string msg);
//使用自定义委托类型定义事件,事件名为DinnerEvent
//public event DinnerHandler DinnerEvent;
//扩展EventArgs类(示例三)
//自定义委托类型,委托包含两个参数
//public delegate void DinnerHandler( object sender, DinnerEventArgs e );
//定义事件
//public event DinnerHandler DinnerEvent;
//扩展EventArgs类(示例四)
public event EventHandler<DinnerEventArgs> DinnerEvent;
//发出事件
public void OnDinnerComing( string msg )
{
//判断是否绑定了事件处理方法
if( null != DinnerEvent )
{
//Console.WriteLine( msg );
//触发事件
DinnerEvent( this, new DinnerEventArgs( msg ) );
}
}
static void Main( string[ ] args )
{
Dinner dinner = new Dinner( );
//实例化朋友对象
Friend friend1 = new Friend( "张三" );
Friend friend2 = new Friend( "李四" );
//使用+=来订阅事件,事件绑定
dinner.DinnerEvent += new EventHandler<DinnerEventArgs>( friend1.SendMessage );
//发出通知,此时只有订阅了事件的对象才能收到通知
dinner.OnDinnerComing( "朋友们,过来我家吃饭啦!" );
Console.ReadKey( );
}
}
}
以上代码通过自定义DinnerEventArgs事件类扩展了EventArgs类,此时DinnerEventArgs带有一个名为Message的事件参数;然后再订阅对象的SendMessage方法中,通过e.Message方式获得了事件数据,并把事件数据输出。