C#中使用事件

C#创建事件
2010-10-03 12:56

C#中使用事件需要的步骤 ?
1.创建一个委托
2.将创建的委托与特定事件关联
3.编写事件处理程序
4.利用编写的事件处理程序生成一个委托实例
5.把这个委托实例添加到产生事件对象的事件列表中去,这个过程又叫订阅事件.

目标:通过一个实例来按步骤说明C#自定义事件如何创建,引发,接收和取消。例子是一个窗体程序,一个按钮和一个标签,点击按钮的时候就触发一个事件得到当前时间,如果秒是后30秒就输出一个Wasn't a right time!!

创建一个事件类型:

1.新建一个窗体应用程序,添加一个button和lebelInfo,name分别为buttonRaise和labelInfo。

2.定义一个委托:

在窗体类的声明部分添加

      
      
  1. public delegate void ActionEventHandler(object sender, ActionCancelEventArgs e);

这里我们声明了一个新的委托类型ActionEventHandler,原因是我们后面要自己定制EventArg类(上面可见就是ActionCancelEventArgs类),方法名必须和委托匹配。

3.定义一个C#自定义事件:

在上面代码后面加上,

      
      
  1. public static event ActionEventHandler Action;

我们定义了一个叫Action的事件,事件定义的语法要求指定与事件相关的委托。

4.创建自己定义的EventArg类:

在程序中定义一个类代码如下:

      
      
  1. namespace WindowsApplication1
  2. {
  3. public class ActionCancelEventArgs : System.ComponentModel.CancelEventArgs
  4. {
  5. string message = String.Empty;
  6. public ActionCancelEventArgs() : base() { }
  7. public ActionCancelEventArgs(bool cancel) : base(cancel) { }
  8. public ActionCancelEventArgs(bool cancel, string message)
  9. : base(cancel)
  10. {
  11. this.message = message;
  12. }
  13. public string Message
  14. {
  15. get { return message; }
  16. set { message = value; }
  17. }
  18. }
  19. }

这个新类ActionCancelEventArgs实际上派生于CancelEventArgs,而CancelEventArgs派生于EventArgs。CancelEventArgs添加了Cancel属性,是一个bool类型,它通知sender对象,接收器希望取消或者停止事件的处理。我们为ActionCancelEventArgs添加一个message属性,包含事件处理时候传递一个事件处理状态的字符串。

所有的基于EventArgs的类都负责在发送器和接收器之间来回传送事件的信息。大多情况下,EventArgs类中使用的信息都被事件处理程序中的接收器对象(这里后来的ActionCancelEventArgs ev)所使用。但是有时候,事件处理程序可以把信息添加到EventArg类中,使之可以用于发送器。我们这里就是这样做的其实(接收器根据状态把信息传给发送器中的message属性了)。

引发事件:

1.通过一种动作来激活Action事件(我们就用点击按钮buttonRaise):

先为buttonRaise按钮添加一个点击事件处理程序:

      
      
  1. private void buttonRaise_Click(object sender, EventArgs e)

2.再在处理程序中用正确的参数调用事件:添加如下代码,

      
      
  1. ActionCancelEventArgs cancelEvent = new ActionCancelEventArgs();
  2. OnAction(this, cancelEvent);

就是先创建一个新的事件数据类型ActionCancelEventArgs,再把它当作参数传递给前面定义的那个Action事件的处理程序(引发事件是通过Action(this, cancelEvent)的,但是我们通过OnAction()来调用之)。这里我们的Action事件就相当我们.Net中的Move,Click事件一样的了,但是目前它还是空的,如果引发了这个事件就会产生一个空引用异常,所以我们如果在其他的类中把Action事件定义为基事件,则只要引发了Action就要定义相关的事件处理程序的。

3.我们定义一个叫OnAction的函数引发事件,(加上On是命名约定)

      
      
  1. protected void OnAction(object sender, ActionCancelEventArgs e)
  2. {
  3. if (Action != null) //捕获空引用错误
  4. Action(sender, e);
  5. }

如果派生一个包含该方法和事件的新类,就必须重写OnAction方法,并且在重写代码中调用base.OnAction(),引发此事件。

接受事件,并且处理之:

1.下面就是定义一个新类BusEntity了:

      
      
  1. namespace WindowsApplication1
  2. {
  3. public class BusEntity
  4. {
  5. string time = String.Empty;
  6. public BusEntity()
  7. {
  8. Form1.Action += new Form1.ActionEventHandler(Form1_Action);
  9. }
  10. private void Form1_Action(object sender, ActionCancelEventArgs e)
  11. {
  12. e.Cancel = !DoActions();
  13. if (e.Cancel)
  14. e.Message = "Wasn't the right time.";
  15. }
  16. private bool DoActions()
  17. {
  18. bool retVal = false;
  19. DateTime tm = DateTime.Now;
  20. if (tm.Second < 30)
  21. {
  22. time = "The time is " + DateTime.Now.ToLongTimeString();
  23. retVal = true;
  24. }
  25. else
  26. time = "";
  27. return retVal;
  28. }
  29. public string TimeString
  30. {
  31. get { return time; }
  32. }
  33. }
  34. }

其中关键代码:

1.构造函数中声明了Form1.Action事件的处理程序(注册事件):

      
      
  1. Form1.Action += new Form1.ActionEventHandler(Form1_Action);

注意这里注册的是Form1中定义的那个Action事件,不是其它地方定义的。

2.Action事件的处理程序(在前面Form1类中通过OnAction()引发的):

      
      
  1. private void Form1_Action(object sender, ActionCancelEventArgs e)

其中的处理是通过调用DoAction函数来的。它返回一个bool值,并且将状态信息赋值给事件数据类型ActionCancelEventArgs的参数的message成员。

3.完善Form1程序:

(1)类中要先新建成员private BusEntity busEntity;

(2)构造函数中初始化之:busEntity = new BusEntity();

(3)完善点击按钮的事件处理,引发并且处理Action事件:

      
      
  1. private void buttonRaise_Click(object sender, EventArgs e)
  2. {
  3. ActionCancelEventArgs cancelEvent = new ActionCancelEventArgs();
  4. OnAction(this, cancelEvent);
  5. if (cancelEvent.Cancel)
  6. labelInfo.Text = cancelEvent.Message;
  7. else
  8. labelInfo.Text = busEntity.TimeString;
  9. }

在补充说明:这里创建了ActionCancelEventArgs对象,接着引发了Action事件,并且传递了新建的ActionCancelEventArgs对象cancelEvent。在调用OnAction方法,引发事件的时候,BusEntity对象中Action事件处理程序的代码就会执行。如果还有其他对象注册了事件,它们同样会执行。记住:如果其他对象也处理了事件Action,它们也会看到同一个ActionCancelEventArgs对象。如果需要确定是哪个对象取消了事件,而且如果多个对象取消了事件,就要在ActionCancelEventArgs类中再包含某种基于列表的数据结构。

取消事件:

在与委托一起注册的处理程序执行完之后,就可以查询ActionCancelEventArgs对象,并且确定它是否被取消了。也就是下面代码:

      
      
  1. if (cancelEvent.Cancel)
  2. labelInfo.Text = cancelEvent.Message;
  3. else
  4. labelInfo.Text = busEntity.TimeString;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值