五月综合缴情婷婷六月,色94色欧美sute亚洲线路二,日韩制服国产精品一区,色噜噜一区二区三区,香港三级午夜理伦三级三

您現(xiàn)在的位置: 365建站網(wǎng) > 365文章 > C# 事件 委托 教程

C# 事件 委托 教程

文章來源:365jz.com     點(diǎn)擊數(shù):286    更新時(shí)間:2009-09-12 17:00   參與評(píng)論

這是我昨天查幫助文檔時(shí)看到的,很不錯(cuò)吧,這是IDE自帶的,所以,有興趣,可以就在幫助里找,方便又權(quán)威,寫得也很易懂。貼上來,讓大家看看,這幫助文檔里的全是好東東啊。

C# 中的“事件”是當(dāng)對(duì)象發(fā)生某些有趣的事情時(shí),類向該類的客戶提供通知的一種方法。事件最常見的用途是用于圖形用戶界面;通常,表示界面中的控件的類具有一些事件,當(dāng)用戶對(duì)控件進(jìn)行某些操作(如單擊某個(gè)按鈕)時(shí),將通知這些事件。

但是事件未必只用于圖形界面。事件為對(duì)象提供一種通常很有用的方法來發(fā)出信號(hào)表示狀態(tài)更改,這些狀態(tài)更改可能對(duì)該對(duì)象的客戶很有用。事件是創(chuàng)建類的重要構(gòu)造塊,這些類可在大量的不同程序中重復(fù)使用。

使用委托來聲明事件。如果您尚未學(xué)習(xí)“委托教程”,您應(yīng)先學(xué)習(xí)它,然后再繼續(xù)。請(qǐng)回憶委托對(duì)象封裝一個(gè)方法,以便可以匿名調(diào)用該方法。事件是類允許客戶為其提供方法(事件發(fā)生時(shí)應(yīng)調(diào)用這些方法)的委托的一種方法。事件發(fā)生時(shí),將調(diào)用其客戶提供給它的委托。

除聲明事件、調(diào)用事件和與事件掛鉤的示例以外,本教程還介紹下列主題:

事件和繼承
接口中的事件
.NET Framework 指南
示例 1
下面的簡單示例展示一個(gè) ListWithChangedEvent 類,該類類似于標(biāo)準(zhǔn)的 ArrayList 類,而且,每當(dāng)列表內(nèi)容更改時(shí),該類均調(diào)用 Changed 事件。這樣一個(gè)通用用途的類可在大型程序中以多種方式使用。

例 如,某字處理器可能包含打開的文檔的列表。每當(dāng)該列表更改時(shí),可能需要通知字處理器中的許多不同對(duì)象,以便能夠更新用戶界面。使用事件,維護(hù)文檔列表的代 碼不需要知道需要通知誰,一旦文檔列表發(fā)生了更改,將自動(dòng)調(diào)用該事件,正確通知每個(gè)需要通知的對(duì)象。使用事件提高了程序的模塊化程度。

// 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 called when the event fires.
代碼討論
聲明事件   若要在類內(nèi)聲明事件,首先必須聲明該事件的委托類型(如果尚未聲明的話)。
public delegate void ChangedEventHandler(object sender, EventArgs e);
委托類型定義傳遞給處理該事件的方法的一組參數(shù)。多個(gè)事件可共享相同的委托類型,因此僅當(dāng)尚未聲明任何合適的委托類型時(shí)才需要執(zhí)行該步驟。

接下來,聲明事件本身。

public event ChangedEventHandler Changed;
聲明事件的方法與聲明委托類型的字段類似,只是關(guān)鍵字 event 在事件聲明前面,在修飾符后面。事件通常被聲明為公共事件,但允許任意可訪問修飾符。

調(diào)用事件   類聲明了事件以后,可以就像處理所指示的委托類型的字段那樣處理該事件。如果沒有任何客戶將委托與該事件掛鉤,該字段將為空;否則該字段引用應(yīng)在調(diào)用該事件時(shí)調(diào)用的委托。因此,調(diào)用事件時(shí)通常先檢查是否為空,然后再調(diào)用事件。
if (Changed != null)
Changed(this, e);
調(diào)用事件只能從聲明該事件的類內(nèi)進(jìn)行。

與事件掛鉤   從聲明事件的類外看,事件像個(gè)字段,但對(duì)該字段的訪問是非常受限制的。只可進(jìn)行如下操作:
在該字段上撰寫新的委托。
從字段(可能是復(fù)合字段)移除委托。
使用 += 和 -= 運(yùn)算符完成此操作。為開始接收事件調(diào)用,客戶代碼先創(chuàng)建事件類型的委托,該委托引用應(yīng)從事件調(diào)用的方法。然后它使用 += 將該委托寫到事件可能連接到的其他任何委托上。

// Add "ListChanged" to the Changed event on "List":
List.Changed += new ChangedEventHandler(ListChanged);
當(dāng)客戶代碼完成接收事件調(diào)用后,它將使用運(yùn)算符 -= 從事件移除其委托。

// Detach the event and delete the list:
List.Changed -= new ChangedEventHandler(ListChanged);
事件和繼承
當(dāng) 創(chuàng)建可以從中派生的通用組件時(shí),事件中有時(shí)出現(xiàn)似乎會(huì)成為問題的情況。由于事件只能從聲明它們的類中調(diào)用,因此派生類不能直接調(diào)用在基類內(nèi)聲明的事件。雖 然這有時(shí)符合需要,但通常使派生類能夠自由調(diào)用事件更合適。這通常通過為事件創(chuàng)建受保護(hù)的調(diào)用方法來實(shí)現(xiàn)。通過調(diào)用該調(diào)用方法,派生類便可以調(diào)用此事件。 為獲得更大的靈活性,調(diào)用方法通常聲明為虛擬的,這允許派生類重寫調(diào)用方法。這使得派生類可以截獲基類正在調(diào)用的事件,有可能對(duì)這些事件執(zhí)行它自己的處 理。

在前面的示例中,這已用 OnChanged 方法實(shí)現(xiàn)。如果需要,派生類可調(diào)用或重寫該方法。

接口中的事件
事件和字段之間的另一個(gè)差異是,事件可放在接口中,而字段不能。當(dāng)實(shí)現(xiàn)接口時(shí),實(shí)現(xiàn)類必須在實(shí)現(xiàn)接口的類中提供相應(yīng)的事件。

.NET Framework 指南
盡管 C# 語言允許事件使用任意委托類型,但“.NET Framework”對(duì)于應(yīng)為事件使用的委托類型有一些更嚴(yán)格的指南。如果打算將您的組件與“.NET Framework”一起使用,您可能希望遵守這些指南。

“.NET Framework”指南指示用于事件的委托類型應(yīng)采用兩個(gè)參數(shù):指示事件源的“對(duì)象源”參數(shù)和封裝事件的其他任何相關(guān)信息的“e”參數(shù)。“e”參數(shù)的類 型應(yīng)從 EventArgs 類派生。對(duì)于不使用其他任何信息的事件,“.NET Framework”已定義了一個(gè)適當(dāng)?shù)奈蓄愋停篍ventHandler。

示例 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;
         // 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.

如對(duì)本文有疑問,請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答!! 點(diǎn)擊進(jìn)入論壇

發(fā)表評(píng)論 (286人查看0條評(píng)論)
請(qǐng)自覺遵守互聯(lián)網(wǎng)相關(guān)的政策法規(guī),嚴(yán)禁發(fā)布色情、暴力、反動(dòng)的言論。
昵稱:
最新評(píng)論
------分隔線----------------------------

其它欄目

· 建站教程
· 365學(xué)習(xí)

業(yè)務(wù)咨詢

· 技術(shù)支持
· 服務(wù)時(shí)間:9:00-18:00
365建站網(wǎng)二維碼

Powered by 365建站網(wǎng) RSS地圖 HTML地圖

copyright © 2013-2024 版權(quán)所有 鄂ICP備17013400號(hào)