电话:0731-83595998
导航

C# 程序员参考--事件教学文章

来源: 2017-08-20 20:22

 本教程展示如何在 C# 中声明事件、调用事件和挂接到事件。

教程

C# 中的“事件”是当对象发生某些有趣的事情时,类向该类的客户提供通知的一种方法。事件最常见的用途是用于图形用户界面;通常,表示界面中的控件的类具有一些事件,当用户对控件进行某些操作(如单击某个按钮)时,将通知这些事件。

但是事件未必只用于图形界面。事件为对象提供一种通常很有用的方法来发出信号表示状态更改,这些状态更改可能对该对象的客户很有用。事件是创建类的重要构造块,这些类可在大量的不同程序中重复使用。

使用委托来声明事件。如果您尚未学习“委托教程”,您应先学习它,然后再继续。请回忆委托对象封装一个方法,以便可以匿名调用该方法。事件是类允许客户为其提供方法(事件发生时应调用这些方法)的委托的一种方法。事件发生时,将调用其客户提供给它的委托。

除声明事件、调用事件和与事件挂钩的示例以外,本教程还介绍下列主题:

示例 1

下面的简单示例展示一个 ListWithChangedEvent 类,该类类似于标准的 ArrayList 类,而且,每当列表内容更改时,该类均调用 Changed 事件。这样一个通用用途的类可在大型程序中以多种方式使用。

例如,某字处理器可能包含打开的文档的列表。每当该列表更改时,可能需要通知字处理器中的许多不同对象,以便能够更新用户界面。使用事件,维护文档列表的代码不需要知道需要通知谁,一旦文档列表发生了更改,将自动调用该事件,正确通知每个需要通知的对象。使用事件提高了程序的模块化程度。

// events1.cs



using System;



namespace MyCollections 



{



   using System.Collections;







   // A delegate type for hooking up change notifications.



   public delegate void ChangedEventHandler(object sender, EventArgs e);







   // A class that works just like ArrayList, but sends event



   // notifications whenever the list changes.



   public class ListWithChangedEvent: ArrayList 



   {



      // An event that clients can use to be notified whenever the



      // elements of the list change.



      public event ChangedEventHandler Changed;







      // Invoke the Changed event; called whenever list changes



      protected virtual void OnChanged(EventArgs e) 



      {



         if (Changed != null)



            Changed(this, e);



      }







      // Override some of the methods that can change the list;



      // invoke event after each



      public override int Add(object value) 



      {



         int i = base.Add(value);



         OnChanged(EventArgs.Empty);



         return i;



      }







      public override void Clear() 



      {



         base.Clear();



         OnChanged(EventArgs.Empty);



      }







      public override object this[int index] 



      {



         set 



         {



            base[index] = value;



            OnChanged(EventArgs.Empty);



         }



      }



   }



}







namespace TestEvents 



{



   using MyCollections;







   class EventListener 



   {



      private ListWithChangedEvent List;







      public EventListener(ListWithChangedEvent list) 



      {



         List = list;



         // Add "ListChanged" to the Changed event on "List".



         List.Changed += new ChangedEventHandler(ListChanged);



      }







      // This will be called whenever the list changes.



      private void ListChanged(object sender, EventArgs e) 



      {



         Console.WriteLine("This is called when the event fires.");



      }







      public void Detach() 



      {



         // Detach the event and delete the list



         List.Changed -= new ChangedEventHandler(ListChanged);



         List = null;



      }



   }







   class Test 



   {



      // Test the ListWithChangedEvent class.



      public static void Main() 



      {



      // Create a new list.



      ListWithChangedEvent list = new ListWithChangedEvent();







      // Create a class that listens to the list's change event.



      EventListener listener = new EventListener(list);







      // Add and remove items from the list.



      list.Add("item 1");



      list.Clear();



      listener.Detach();



      }



   }



}

输出

This is called when the event fires.



This is calle

 

[1] [2] [3] 下一页  

 

d when the event fires.

代码讨论

事件和继承

当创建可以从中派生的通用组件时,事件中有时出现似乎会成为问题的情况。由于事件只能从声明它们的类中调用,因此派生类不能直接调用在基类内声明的事件。虽然这有时符合需要,但通常使派生类能够自由调用事件更合适。这通常通过为事件创建受保护的调用方法来实现。通过调用该调用方法,派生类便可以调用此事件。为获得更大的灵活性,调用方法通常声明为虚拟的,这允许派生类重写调用方法。这使得派生类可以截获基类正在调用的事件,有可能对这些事件执行它自己的处理。

在前面的示例中,这已用 OnChanged 方法实现。如果需要,派生类可调用或重写该方法。

接口中的事件

事件和字段之间的另一个差异是,事件可放在接口中,而字段不能。当实现接口时,实现类必须在实现接口的类中提供相应的事件。

.NET Framework 指南

尽管 C# 语言允许事件使用任意委托类型,但“.NET Framework”对于应为事件使用的委托类型有一些更严格的指南。如果打算将您的组件与“.NET Framework”一起使用,您可能希望遵守这些指南。

“.NET Framework”指南指示用于事件的委托类型应采用两个参数:指示事件源的“对象源”参数和封装事件的其他任何相关信息的“e”参数。“e”参数的类型应从 EventArgs 类派生。对于不使用其他任何信息的事件,“.NET Framework”已定义了一个适当的委托类型:EventHandler

示例 2

下面的示例是“示例 1”的修改版本,它遵守“.NET Framework”指南。该示例使用EventHandler 委托类型。

// events2.cs



using System;



namespace MyCollections 



{



   using System.Collections;







   // A class that works just like ArrayList, but sends event



   // notifications whenever the list changes:



   public class ListWithChangedEvent: ArrayList 



   {



      // An event that clients can use to be notified whenever the



      // elements of the list change:



      public event EventHandler Changed;







      // Invoke the Changed event; called whenever list changes:



      protected virtual void OnChanged(EventArgs e) 



      {



         if (Changed != null)



            Changed(this,e);



      }







      // Override some of the methods that can change the list;



      // invoke event after each:



      public override int Add(object value) 



      {



         int i = base.Add(value);



         OnChanged(EventArgs.Empty);



         return i;



      }







      public override void Clear() 



      {



         base.Clear();



         OnChanged(EventArgs.Empty);



      }







      public override object this[int index] 



      {



         set 



         {



            base[index] = value;



            OnChanged(EventArgs.Empty);



         }



      }



   }



}







namespace TestEvents 



{



   using MyCollections;







   class EventListener 



   {



      private ListWithChangedEvent List;







      public EventListener(ListWithChangedEvent list) 



      {



         List = list;



 

 

上一页  [1] [2] [3] 下一页  

 

// Add "ListChanged" to the Changed event on "List": List.Changed += new EventHandler(ListChanged); } // This will be called whenever the list changes: private void ListChanged(object sender, EventArgs e) { Console.WriteLine("This is called when the event fires."); } public void Detach() { // Detach the event and delete the list: List.Changed -= new EventHandler(ListChanged); List = null; } } class Test { // Test the ListWithChangedEvent class: public static void Main() { // Create a new list: ListWithChangedEvent list = new ListWithChangedEvent(); // Create a class that listens to the list's change event: EventListener listener = new EventListener(list); // Add and remove items from the list: list.Add("item 1"); list.Clear(); listener.Detach(); } } }

输出

This is called when the event fires.



This is called when the event fires.



 

 

 

上一页  [1] [2] [3] 

编辑推荐:

下载Word文档

温馨提示:因考试政策、内容不断变化与调整,长理培训网站提供的以上信息仅供参考,如有异议,请考生以权威部门公布的内容为准! (责任编辑:长理培训)

网络课程 新人注册送三重礼

已有 22658 名学员学习以下课程通过考试

网友评论(共0条评论)

请自觉遵守互联网相关政策法规,评论内容只代表网友观点!

最新评论

点击加载更多评论>>

精品课程

更多
10781人学习

免费试听更多

相关推荐
图书更多+
  • 电网书籍
  • 财会书籍
  • 其它工学书籍
拼团课程更多+
  • 电气拼团课程
  • 财会拼团课程
  • 其它工学拼团
热门排行

长理培训客户端 资讯,试题,视频一手掌握

去 App Store 免费下载 iOS 客户端