我理解事件的目的,特别是在创建用户界面的上下文中。我认为这是创建事件的原型:
public void EventName(object sender, EventArgs e);
事件处理程序做什么,为什么需要它们,以及如何创建一个?
我理解事件的目的,特别是在创建用户界面的上下文中。我认为这是创建事件的原型:
public void EventName(object sender, EventArgs e);
事件处理程序做什么,为什么需要它们,以及如何创建一个?
当前回答
要理解事件处理程序,您需要理解委托。在c#中,您可以将委托视为指向方法的指针(或引用)。这很有用,因为指针可以作为值传递。
委托的核心概念是它的签名或形状。即(1)返回类型和(2)输入参数。例如,如果我们创建一个委托void MyDelegate(object sender, EventArgs e),它只能指向返回void的方法,并接受一个对象和EventArgs。有点像一个方洞和一个方钉子。因此,我们说这些方法与委托具有相同的签名或形状。
So knowing how to create a reference to a method, let's think about the purpose of events: we want to cause some code to be executed when something happens elsewhere in the system - or "handle the event". To do this, we create specific methods for the code we want to be executed. The glue between the event and the methods to be executed are the delegates. The event must internally store a "list" of pointers to the methods to call when the event is raised.* Of course, to be able to call a method, we need to know what arguments to pass to it! We use the delegate as the "contract" between the event and all the specific methods that will be called.
因此默认的EventHandler(以及许多类似的)表示方法的特定形状(同样是void/object-EventArgs)。当你声明一个事件时,你是在说该事件将调用哪种形状的方法(EventHandler),通过指定一个委托:
//This delegate can be used to point to methods
//which return void and take a string.
public delegate void MyEventHandler(string foo);
//This event can cause any method which conforms
//to MyEventHandler to be called.
public event MyEventHandler SomethingHappened;
//Here is some code I want to be executed
//when SomethingHappened fires.
void HandleSomethingHappened(string foo)
{
//Do some stuff
}
//I am creating a delegate (pointer) to HandleSomethingHappened
//and adding it to SomethingHappened's list of "Event Handlers".
myObj.SomethingHappened += new MyEventHandler(HandleSomethingHappened);
//To raise the event within a method.
SomethingHappened("bar");
(*这是。net中事件的关键,它揭开了“魔法”的面纱——一个事件实际上只是一组具有相同“形状”的方法。列表存储在事件所在的位置。当事件被“引发”时,它实际上只是“遍历这个方法列表并调用每个方法,使用这些值作为参数”。分配事件处理程序只是将您的方法添加到要调用的方法列表的一种更漂亮、更简单的方式)。
其他回答
//This delegate can be used to point to methods
//which return void and take a string.
public delegate void MyDelegate(string foo);
//This event can cause any method which conforms
//to MyEventHandler to be called.
public event MyDelegate MyEvent;
//Here is some code I want to be executed
//when SomethingHappened fires.
void MyEventHandler(string foo)
{
//Do some stuff
}
//I am creating a delegate (pointer) to HandleSomethingHappened
//and adding it to SomethingHappened's list of "Event Handlers".
myObj.MyEvent += new MyDelegate (MyEventHandler);
我同意KE50的观点,除了我认为'event'关键字是'ActionCollection'的别名,因为事件包含了要执行的操作的集合(例如。委托)。
using System;
namespace test{
class MyTestApp{
//The Event Handler declaration
public delegate void EventAction();
//The Event Action Collection
//Equivalent to
// public List<EventAction> EventActions=new List<EventAction>();
//
public event EventAction EventActions;
//An Action
public void Hello(){
Console.WriteLine("Hello World of events!");
}
//Another Action
public void Goodbye(){
Console.WriteLine("Goodbye Cruel World of events!");
}
public static void Main(){
MyTestApp TestApp = new MyTestApp();
//Add actions to the collection
TestApp.EventActions += TestApp.Hello;
TestApp.EventActions += TestApp.Goodbye;
//Invoke all event actions
if (TestApp.EventActions!= null){
//this peculiar syntax hides the invoke
TestApp.EventActions();
//using the 'ActionCollection' idea:
// foreach(EventAction action in TestApp.EventActions)
// action.Invoke();
}
}
}
}
发布者:事件发生的地方。发布者应该指定类使用哪个委托,并生成必要的参数,将这些参数和自身传递给委托。
订阅者:响应发生的地方。订阅者应指定响应事件的方法。这些方法应该采用与委托相同类型的参数。订阅者然后将此方法添加到发布者的委托。
因此,当事件在publisher中发生时,delegate将收到一些事件参数(数据等),但publisher不知道所有这些数据将会发生什么。订阅者可以在自己的类中创建方法来响应发布者类中的事件,这样订阅者就可以响应发布者的事件。
这实际上是一个事件处理程序的声明——一个在触发事件时被调用的方法。要创建一个事件,你可以这样写:
public class Foo
{
public event EventHandler MyEvent;
}
然后你可以像这样订阅这个事件:
Foo foo = new Foo();
foo.MyEvent += new EventHandler(this.OnMyEvent);
OnMyEvent()的定义如下:
private void OnMyEvent(object sender, EventArgs e)
{
MessageBox.Show("MyEvent fired!");
}
每当Foo触发MyEvent,那么你的OnMyEvent处理程序将被调用。
你不必总是使用EventArgs的实例作为第二个参数。如果你想包含额外的信息,你可以使用一个从EventArgs派生的类(根据惯例EventArgs是基类)。例如,如果你查看WinForms中的Control上定义的一些事件,或者WPF中的FrameworkElement上定义的一些事件,你可以看到将附加信息传递给事件处理程序的事件示例。
我对这些事件的理解是;
委托:
保存要执行的方法/方法的引用的变量。这使得像传递变量一样传递方法成为可能。
创建和调用事件的步骤:
事件是委托的实例 由于事件是委托的实例,因此我们必须首先定义委托。 指定在事件触发时执行的方法/方法(调用委托) 触发事件(调用委托)
例子:
using System;
namespace test{
class MyTestApp{
//The Event Handler declaration
public delegate void EventHandler();
//The Event declaration
public event EventHandler MyHandler;
//The method to call
public void Hello(){
Console.WriteLine("Hello World of events!");
}
public static void Main(){
MyTestApp TestApp = new MyTestApp();
//Assign the method to be called when the event is fired
TestApp.MyHandler = new EventHandler(TestApp.Hello);
//Firing the event
if (TestApp.MyHandler != null){
TestApp.MyHandler();
}
}
}
}