C#自定义事件实现简介

目标:通过一个实例来按步骤说明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.  
  7.       public ActionCancelEventArgs() : base() { }  
  8.  
  9.       public ActionCancelEventArgs(bool cancel) : base(cancel) { }  
  10.  
  11.       public ActionCancelEventArgs(bool cancel, string message)  
  12.          : base(cancel)  
  13.       {  
  14.          this.message = message;  
  15.       }  
  16.  
  17.       public string Message  
  18.       {  
  19.          get { return message; }  
  20.          set { message = value; }  
  21.       }  
  22.    }  
  23. }  
  24.  

    这个新类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);  

 

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

接受事件,并且处理之:

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

 

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

    其中关键代码:

    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; 

    总结:上面就是我个人通过《Professional C# 2005 with .Net 3.0》一书中的相关部分,总结出的如何利用事件和事件中基于EventArgs的对象,在应用程序中传递信息的,生成C#自定义事件。程序示例来源于此教程。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C# 中,自定义事件是一个非常重要的概念,它使得我们可以在特定的情况下触发一个事件,并且在事件发生时执行特定的操作。自定义事件的基本思想是,定义一个委托类型来表示事件,然后定义一个事件来注册和触发该委托。 下面是定义自定义事件的一般步骤: 1. 定义一个委托类型 在 C# 中,委托类型是一种特殊的类型,它可以存储一个或多个方法的引用,可以用来表示事件。例如,假设我们要定义一个事件,当某个按钮被单击时触发,我们可以定义一个委托类型如下: ``` public delegate void ClickEventHandler(object sender, EventArgs e); ``` 这个委托类型表示一个方法,它有两个参数:一个是事件的发送者,另一个是事件参数。在这个委托类型中,我们使用了 C# 中内置的 EventArgs 类来表示事件参数。 2. 定义一个事件 定义一个事件需要两个步骤:首先,我们需要在类中定义一个委托类型的变量,用来存储注册到事件上的方法;其次,我们需要定义一个公共的事件,用来注册和触发该委托。 例如,假设我们要定义一个名为 Button 的类,该类有一个 Click 事件,我们可以定义如下: ``` public class Button { // 定义一个委托类型的变量 private ClickEventHandler clickHandler; // 定义一个公共的事件 public event ClickEventHandler Click { add { clickHandler += value; } remove { clickHandler -= value; } } // 触发事件的方法 protected virtual void OnClick(EventArgs e) { if (clickHandler != null) clickHandler(this, e); } // 模拟按钮被单击的方法 public void SimulateClick() { OnClick(EventArgs.Empty); } } ``` 在这个示例中,我们首先定义了一个名为 clickHandler 的委托类型的变量,用来存储注册到 Click 事件上的方法。然后,我们定义了一个公共的事件 Click,它使用了 C# 中内置的 event 关键字,并通过 add 和 remove 访问器来实现注册和注销事件的方法。接着,我们定义了一个受保护的虚拟方法 OnClick,用来触发 Click 事件,并在其中调用了 clickHandler 变量所存储的所有方法。最后,我们定义了一个模拟按钮被单击的方法 SimulateClick,用来触发 Click 事件。 3. 注册事件处理方法 要在事件发生时执行特定的操作,我们需要将一个方法注册到事件上。在 C# 中,我们可以使用 += 运算符来注册方法,使用 -= 运算符来注销方法。 例如,假设我们要在 Button 类的 Click 事件发生时弹出一个消息框,我们可以编写如下代码: ``` Button button = new Button(); button.Click += (sender, e) => MessageBox.Show("Button clicked!"); button.SimulateClick(); ``` 在这个示例中,我们首先创建了一个 Button 对象 button,并使用 += 运算符将一个匿名方法注册到 button 的 Click 事件上。在匿名方法中,我们使用了 MessageBox 类来弹出一个消息框,显示按钮被单击的信息。接着,我们调用了 button 的 SimulateClick 方法,来模拟按钮被单击的操作。当 SimulateClick 方法被调用时,会触发 Click 事件,并执行注册到该事件上的方法。 以上就是 C# 中定义自定义事件的一般步骤。通过自定义事件,我们可以很方便地实现类似于 Windows 应用程序中的事件机制,使得程序更加灵活和易于维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值