首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 事件機制深度解析(下):預定義事件、EventHandler 與自訂事件參數

     編輯:關於C語言

前言

承接上篇,本文深入 .NET 框架預定義事件模式、EventHandler 委派慣例、自訂 EventArgs 傳遞豐富資料,以及事件參數在實戰中的應用技巧。

一、.NET 預定義事件模式

1.1 EventHandler 委派定義

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

所有符合 void Method(object sender, EventArgs e) 簽名的方法,皆可作為 Control.Click 等標準事件的處理器。

1.2 Button.Click 事件內部實作

public class Button : Control
{
    public event EventHandler Click; // 直接使用 EventHandler

    protected virtual void OnClick(EventArgs e)
    {
        Click?.Invoke(this, e);
    }
}

1.3 訂閱標準事件

this.button1.Click += new EventHandler(this.Button1_Click);
// 或簡寫
this.button1.Click += Button1_Click;

private void Button1_Click(object sender, EventArgs e)
{
    // sender 為 button1, e 為 EventArgs.Empty
}

二、自訂事件參數傳遞豐富資訊

2.1 繼承 EventArgs

public class RegisterOkArgs : EventArgs
{
    public string EventInfo { get; }
    public RegisterOkArgs(string info) => EventInfo = info;
}

2.2 專用委派與事件

public delegate void RegisterOkHandler(object sender, RegisterOkArgs e);

public class Student
{
    public string Name { get; set; }
    public event RegisterOkHandler RegisterOK;

    public void Register()
    {
        Console.WriteLine("Register Method");
        OnRegisterOK(new RegisterOkArgs($"Student Name: {Name}"));
    }

    protected virtual void OnRegisterOK(RegisterOkArgs e)
    {
        RegisterOK?.Invoke(this, e);
    }
}

2.3 訂閱者接收強型別參數

static void Main()
{
    var s1 = new Student { Name = "Student1" };
    s1.RegisterOK += Student_RegisterOK;
    s1.Register();
}

static void Student_RegisterOK(object sender, RegisterOkArgs e)
{
    Console.WriteLine(e.EventInfo); // 輸出: Student Name: Student1
}

三、事件參數的進階應用

3.1 CancelEventArgs:可取消操作

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (MessageBox.Show("確定關閉?", "確認", MessageBoxButtons.YesNo) == DialogResult.No)
        e.Cancel = true; // 取消關閉
}

3.2 屬性變更通知

public class Person : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get => _name;
        set
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged(new PropertyChangedEventArgs(nameof(Name)));
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        => PropertyChanged?.Invoke(this, e);
}

四、事件存取器

自訂 add/remove 控制訂閱邏輯 (如弱事件模式):

private EventHandler _click;
public event EventHandler Click
{
    add => _click += value;
    remove => _click -= value;
}

五、最佳實務檢查清單

  • ✅ 使用 EventHandler<TEventArgs> 避免自訂委派型別
  • ✅ 提供 protected virtual OnEventName 供衍生類別擴充
  • ✅ 事件參數類別命名以 EventArgs 結尾
  • ✅ 引發事件前檢查 null (或用 ?.Invoke)
  • ✅ 避免在事件處理器中執行長時間阻塞工作

結語

掌握 EventHandler 模式與自訂 EventArgs,能讓事件系統既符合 .NET 慣例、又能攜帶豐富領域資料,構建清晰、可擴充的元件通訊架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved