一、概念
EventArgs
是.net框架中的一个基类,是所有事件参数类的父类。当事件被触发时,事件处理程序接收到一个包含事件数据的对象,这个事件数据所在的类就是Args的一个子类。
public class EventArgs {
public static readonly EventArgs Empty = new EventArgs();
public EventArgs() { }
}
从上面的代码可以看出,EventArgs并没有包含太多的内容,旨在为派生类提供一个基础。
二、事件处理
在c#中,如果我们想要自定义事件,我们必须先定义一个委托类型,然后使用关键字event声明一个事件并绑定上刚才定义的委托类型。下面给出一个简单的例子。 定义委托类型:
public delegate void EventHandler(object sender, EventArgs e);
定义事件:
public class MyClass {
public event EventHandler MyEvent;
}
在上面的代码中,通过event关键字声明了一个名为MyEvent的事件,类型为EventHandler,该事件在MyClass中被引发。 那么在事件的触发过程中,EventHandler对参数的传递使用了EventArgs作为基础类。在事件触发时,可以向事件处理程序传递EventArgs或其派生类的对象,以便提供与事件相关的数据。示例如下:
public class MyEventArgs: EventArgs {
public int Value { get; set; }
}
public class MyClass {
public event EventHandler<MyEventArgs> MyEvent;
public void RaiseEvent() {
var args = new MyEventArgs { Value = 42 };
MyEvent?.Invoke(this, args);
}
}
public class Program {
private static void Main(string[] args) {
var myClass = new MyClass();
myClass.MyEvent += MyClass_MyEvent;
myClass.RaiseEvent();
}
private static void MyClass_MyEvent(object sender, MyEventArgs e) {
Console.WriteLine($"MyEvent handled! The value is {e.Value}.");
}
}
// 输出:
// MyEvent handled! The value is 42.
在上面的代码中,MyClass类中定义了MyEvent,这个事件使用了泛型委托类型,并使用了自定义的派生类MyEventArgs。事件被触发时,生成了一个新的MyEventArgs对象并将其传递给处理程序,从而可以在事件处理程序中访问该事件的data(Value属性)。MyClass类的RaiseEvent()方法通过调用MyEvent.Invoke()方法来触发该事件。
三、实际使用
EventArgs最常见的用法是作为一些标准事件如Button.Click和KeyPress的参数。当控件上发生了这样的事件时,系统会将一个包含事件数据的EventArgs对象,以及控件的引用,传递给注册的事件处理程序。 下面给出一个自定义事件的例子,该事件用于通知观察者在账户余额发生变化时更新UI。如果你有一个基于事件的账户对象,你可能想要添加一个事件,以使UI在余额变化时能够及时匹配。在这样的情况下,EventArgs类无法满足我们的需求,我们需要自定义一个类来存储有关余额变更的数据,如下:
public class AccountEventArgs : EventArgs {
public decimal Balance { get; set; } // 新的账户余额
public AccountEventArgs(decimal balance) {
Balance = balance;
}
}
public class Account {
private decimal _balance;
public EventHandler<AccountEventArgs> OnBalanceChanged;
public decimal Balance {
get => _balance;
set {
_balance = value;
OnBalanceChanged?.Invoke(this, new AccountEventArgs(_balance));
}
}
}
public class Program {
private static void Main(string[] args) {
var account = new Account { Balance = 100 };
account.OnBalanceChanged += Account_OnBalanceChanged;
account.Balance -= 50;
account.Balance += 200;
}
private static void Account_OnBalanceChanged(object sender, AccountEventArgs e) {
Console.WriteLine($"The balance changed to {e.Balance}");
}
}
// 输出:
// The balance changed to 50
// The balance changed to 250
在上面的代码中,Account在setter中触发了OnBalanceChanged事件,该事件使用AccountEventArgs类来传递余额数据。在Main方法中,我们在account对象上注册Account_OnBalanceChanged方法来处理OnBalanceChanged事件。随着balance的减去50和增加200,Account_OnBalanceChanged被调用来处理这些变化,并输出消息。
四、结论
EventArgs提供了一种在触发事件时传递数据的方法,被广泛应用于各种类型的事件中。此外,自定义EventArgs子类可用于定义特定事件的数据,以便于事件处理程序可以访问事件的特定内容。对于需要自定义事件的程序员来说,熟悉EventArgs的使用使得更加容易地实现事件。