承接上篇,本文深入 .NET 框架預定義事件模式、EventHandler 委派慣例、自訂 EventArgs 傳遞豐富資料,以及事件參數在實戰中的應用技巧。
public delegate void EventHandler(object sender, EventArgs e);
所有符合 void Method(object sender, EventArgs e) 簽名的方法,皆可作為 Control.Click 等標準事件的處理器。
public class Button : Control
{
public event EventHandler Click; // 直接使用 EventHandler
protected virtual void OnClick(EventArgs e)
{
Click?.Invoke(this, e);
}
}
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
}
public class RegisterOkArgs : EventArgs
{
public string EventInfo { get; }
public RegisterOkArgs(string info) => EventInfo = info;
}
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);
}
}
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
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("確定關閉?", "確認", MessageBoxButtons.YesNo) == DialogResult.No)
e.Cancel = true; // 取消關閉
}
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 慣例、又能攜帶豐富領域資料,構建清晰、可擴充的元件通訊架構。