如何訂閱及取消訂閱事件 (C# 程式設計手冊)

如果您想要撰寫在引發事件時所呼叫的自訂程式碼,您可以訂閱由其他類別發行的事件。 例如,您可以訂閱某個按鈕的 click 事件,讓應用程式在使用者按下該按鈕時執行某項動作。

使用 Visual Studio IDE 訂閱事件

  1. 如果看不到 [屬性] 視窗,請在 [設計] 檢視中,以滑鼠右鍵按一下您要建立事件處理常式的表單或控制項,然後選取 [屬性]

  2. 在 [屬性] 視窗頂端,按一下事件圖示。

  3. 按兩下您要建立的事件,例如 Load 事件。

    Visual C# 會建立空的事件處理常式方法,並將其新增至您的程式碼。 您也可以在 [程式碼] 檢視中手動新增程式碼。 例如,下列程式碼行會宣告一個事件處理常式方法,該方法將會在 Form 類別引發 Load 事件時呼叫。

    private void Form1_Load(object sender, System.EventArgs e)
    {
        // Add your form load event handling code here.
    }
    

    訂閱事件所需的程式碼行也會在專案之 Form1.Designer.cs 檔案的 InitializeComponent 方法中自動產生。 看起來像這樣:

    this.Load += new System.EventHandler(this.Form1_Load);  
    

以程式設計方式訂閱事件

  1. 定義事件處理常式方法,其簽章與事件的委派簽章相符。 例如,如果事件是以 EventHandler 委派類型為基礎,則下列程式碼代表方法 Stub:

    void HandleCustomEvent(object sender, CustomEventArgs a)  
    {  
       // Do something useful here.  
    }  
    
  2. 請使用加法指派運算子 (+=) 來將事件處理常式附加到事件。 在下列範例中,假設名為 publisher 的物件具有名為 RaiseCustomEvent 的事件。 請注意,subscriber 類別需要參考 publisher 類別,才能訂閱其事件。

    publisher.RaiseCustomEvent += HandleCustomEvent;  
    

    您也可以使用 lambda 運算式指定事件處理常式:

    public Form1()  
    {  
        InitializeComponent();  
        this.Click += (s,e) =>
            {
                MessageBox.Show(((MouseEventArgs)e).Location.ToString());
            };
    }  
    

使用匿名語言函式訂閱事件

如果您稍後不需要取消訂閱事件,您可以使用加法指派運算子 (+=) 將匿名語言函式附加為事件處理常式。 在下列範例中,假設名為 publisher 的物件具有名為 RaiseCustomEvent 的事件,而且也已定義 CustomEventArgs 類別來包含特定類型的特製化事件資訊。 請注意,subscriber 類別需要參考 publisher,才能訂閱其事件。

publisher.RaiseCustomEvent += (object o, CustomEventArgs e) =>
{  
  string s = o.ToString() + " " + e.ToString();  
  Console.WriteLine(s);  
};  

如果使用了匿名函式訂閱事件,則您無法輕易取消訂閱事件。 若要在這種案例下取消訂閱,請回到訂閱事件所在的程式碼,將此匿名語言函式儲存在委派變數中,然後將委派新增至事件。 如果您稍後必須在程式碼中取消訂閱事件,建議您不要使用匿名函式訂閱事件。 如需匿名函式的資訊,請參閱 Lambda 運算式

取消訂閱

若要防止在引發事件時叫用事件處理常式,請取消訂閱事件。 為了避免資源流失,請先取消訂閱事件,再處置訂閱者物件。 在取消訂閱事件之前,發行物件的事件之下的多點傳送委派都會參考封裝訂閱者事件處理常式的委派。 只要發行物件還有該參考,記憶體回收就不會刪除訂閱者物件。

取消訂閱事件

  • 使用減法指派運算子 (-=) 取消訂閱事件:

    publisher.RaiseCustomEvent -= HandleCustomEvent;  
    

    在所有訂閱者都已取消訂閱事件之後,publisher 類別中的事件執行個體會設定為 null

另請參閱