event(C++ 组件扩展)
event 关键字声明事件,该事件通知注册订户(事件处理程序)有相关事情发生。
所有运行时
C++/CX 支持申明事件成员或事件块。 事件成员是声明事件块的简短表示法。 默认情况下,事件成员声明在事件块中显式声明的 add(),remove() 和 raise() 功能。 要自定义事件成员中的功能,请声明事件块并重写需要的功能。
语法
// event data member
modifier event delegate^ event_name;
// event block
modifier event delegate^ event_name
{
modifier return_value add(delegate^ name);
modifier void remove(delegate^ name);
modifier void raise(parameters);
}
参数
modifier
可用于事件声明或事件访问器方法的修饰符。可能的值为 static 和 virtual。delegate
委托,事件处理程序必须与此委托的签名匹配。event_name
事件的名称。return_value
事件访问器方法的返回值。若要验证,则返回类型必须为 void。parameters
(可选)raise 方法的参数,与委托delegate参数的签名匹配。
备注
事件是委托和成员函数(事件处理程序)之间的关联,响应事件的触发并允许任何类的客户端注册符合签名和基础委托返回类型的方法。
有两类事件声明:
事件数据成员
编译器以委托类型成员的形式自动创建事件存储,并创建内部 add()、remove() 和 raise() 成员函数。 事件数据成员必须在类中声明。 委托的返回类型必须与事件处理程序的返回类型相匹配。事件块
事件块使您可显式声明和自定义 add()、remove()和 raise() 方法的行为。
您可以使用 operators+= 和 operator-= 来添加或删除事件处理程序,或显式调用 add() 和 remove() 方法。
event 为区分上下文的关键字;请参见 上下文相关的关键字(C++ 组件扩展)。
Windows 运行时
备注
有关事件的更多信息,请参见 事件 (C++/CX)。
如果想要添加并随后移除事件处理程序,则必须保存由添加操作返回的 EventRegistrationToken 结构。 在随后的移除操作中,必须使用已保存的 EventRegistrationToken 结构标识待移除的事件处理程序。
要求
编译器选项:/ZW
公共语言运行时
event 关键字使您可以声明事件。 事件是类在相关事情发生时发出通知的方法。
语法
// event data member
modifier event delegate^ event_name;
// event block
modifier event delegate^ event_name
{
modifier return_value add(delegate^ name);
modifier void remove(delegate^ name);
modifier void raise(parameters);
}
参数
modifier
可用于事件声明或事件访问器方法的修饰符。可能的值为 static 和 virtual。delegate
委托,事件处理程序必须与此委托的签名匹配。event_name
事件的名称。return_value
事件访问器方法的返回值。若要验证,则返回类型必须为 void。parameters
(可选)raise 方法的参数,与委托delegate参数的签名匹配。
备注
事件是委托和成员函数(事件处理程序)之间的关联,响应事件的触发并允许任何类的客户端注册符合签名和基础委托返回类型的方法。
委托可以具有一个或多个关联方法,这些方法可以在您的代码表明事件已发生时调用。 在一个程序中的事件可用于其他面向 .NET framework 公共语言运行时的程序。 有关示例请参见引发在不同的程序集中定义的事件。
有两类事件声明:
事件数据成员
委托类型成员形式的事件存储空间由针对数据成员事件的编译器创建。事件数据成员必须在类中声明。 这也称为一个常用事件(请参见下面的代码示例)。事件块
事件块允许您通过实施添加、移除和引发的方法来自定义添加、移除和引发方法的行为。 添加、移除和引发方法的签名必须与委托的签名相匹配。事件块并非数据成员,任何将其作为事件成员使用的操作都将产生编译器错误。 有关示例请参见定义事件访问器方法。
事件处理程序的返回类型必须与委托的返回类型匹配。
在 .NET Framework 中,您可以将数据成员视为方法本身(即,其对应委托的 Invoke 方法)。 您必须预定义用于声明托管事件数据成员的委托类型。 相反,如果尚未定义对应的托管委托,则托管事件方法将隐式定义它。有关示例,请参阅本主题结尾处的代码示例。
当声明托管事件时,您可以在事件处理程序添加或移除时使用运算符 += 和 -= 来指定将调用的添加和移动访问器。 添加、移除和引发方法可以显式调用。
为创建并使用 Visual C++ 中的事件,必须执行以下步骤:
创建或标识委托。 如果您定义事件,还必须确保具有与 event 关键字一起使用的委托。 如果事件在 .NET Framework 等中已预定义,则事件使用者只需知道委托的名称。
创建的类包含:
由委派创建的事件。
(可选)存在一种验证用 event 关键字声明的委托实例的方法。 否则,此逻辑必须放置在激发事件的代码中。
调用事件的方法。 这些方法可以是某些基类功能的重写。
此类定义了此事件。
定义一或多个将方法与事件连接的类。 这些类中的每一个都将会将一个或多个方法与基类中的事件相关联。
使用事件:
为包含事件声明的类创建对象。
为包含事件定义的类创建对象。
有关 C++/CLI 事件的更多信息,请参见
要求
编译器选项:/clr
示例
示例
以下代码示例演示了宣布委托、事件和事件处理程序对;订阅(添加)事件处理程序;调用事件处理程序;然后取消订阅(移除)事件处理程序。
// mcppv2_events.cpp
// compile with: /clr
using namespace System;
// declare delegates
delegate void ClickEventHandler(int, double);
delegate void DblClickEventHandler(String^);
// class that defines events
ref class EventSource {
public:
event ClickEventHandler^ OnClick; // declare the event OnClick
event DblClickEventHandler^ OnDblClick; // declare OnDblClick
void FireEvents() {
// raises events
OnClick(7, 3.14159);
OnDblClick("Hello");
}
};
// class that defines methods that will called when event occurs
ref class EventReceiver {
public:
void OnMyClick(int i, double d) {
Console::WriteLine("OnClick: {0}, {1}", i, d);
}
void OnMyDblClick(String^ str) {
Console::WriteLine("OnDblClick: {0}", str);
}
};
int main() {
EventSource ^ MyEventSource = gcnew EventSource();
EventReceiver^ MyEventReceiver = gcnew EventReceiver();
// hook handler to event
MyEventSource->OnClick += gcnew ClickEventHandler(MyEventReceiver, &EventReceiver::OnMyClick);
MyEventSource->OnDblClick += gcnew DblClickEventHandler(MyEventReceiver, &EventReceiver::OnMyDblClick);
// invoke events
MyEventSource->FireEvents();
// unhook handler to event
MyEventSource->OnClick -= gcnew ClickEventHandler(MyEventReceiver, &EventReceiver::OnMyClick);
MyEventSource->OnDblClick -= gcnew DblClickEventHandler(MyEventReceiver, &EventReceiver::OnMyDblClick);
}
Output
示例
以下代码示例演示了用于生成简单事件的 raise 方法:如果该事件具有一个或多个订户,则隐式调用 raise 方法或显式调用该委托。 如果委托的返回类型不是 void 且事件订户为零,则raise 方法返回委托类型的默认值。 如果没有事件订户,可轻松返回调用 raise 方法且不会引发异常。 如果委托的返回类型不是 void,则返回委托类型。
// trivial_events.cpp
// compile with: /clr /c
using namespace System;
public delegate int Del();
public ref struct C {
int i;
event Del^ MyEvent;
void FireEvent() {
i = MyEvent();
}
};
ref struct EventReceiver {
int OnMyClick() { return 0; }
};
int main() {
C c;
c.i = 687;
c.FireEvent();
Console::WriteLine(c.i);
c.i = 688;
EventReceiver^ MyEventReceiver = gcnew EventReceiver();
c.MyEvent += gcnew Del(MyEventReceiver, &EventReceiver::OnMyClick);
Console::WriteLine(c.i);
}
Output
0