event (Visual C++)

The event keyword lets you declare an event. An event is a way for a class to provide notifications when something of interest happens.

modifier event delegate ^ event_name;   // event data member
modifier event delegate ^ event_name 
{
   modifier return_value add (delegate ^ name);
   modifier return_value remove(delegate ^ name);
   modifier return_value raise(parameters);
}   // event block

Parameters

  • delegate
    The delegate, whose signature the event handler must match.

  • event_name
    The name of the event.

  • modifier
    A modifier that can be used on either the event declaration or on an event accessor method. Possible values are static and virtual.

  • name
    The local name of the delegate parameter.

  • parameters(optional)
    Parameter(s) for the raise method, must match the signature of the delegate.

  • return_value
    The return value of the event accessor method. To be verifiable, the return type must be void.

Remarks

An event is an association between a delegate and a member function (event handler) that responds to the triggering of the event and allows clients from any class to register methods that comply with the signature and return type of the underlying delegate.

The delegate can have one or more associated methods that will be called when your code indicates that the event has occurred. An event in one program can be made available to other programs that target the .NET Framework common language runtime. See Raising an Event Defined in a Different Assembly for a sample.

There are two kinds of events declarations:

  • Event data members
    Storage for the event, in the form of a member of the delegate type, is created by the compiler for data member events. An event data member must be declared inside a class. This is also known as a trivial event (see code sample below.)

  • Event Blocks
    Event blocks let you customize the behavior of the add, remove, and raise methods, by implementing add, remove, and raise methods. The signature of the add, remove, and raise methods must match the signature of the delegate. Event block events are not data members and any use as a data member will generate a compiler error. See Defining Event Accessor Methods for a sample.

The return type of the event handler must match the return type of the delegate.

In the .NET Framework, you can treat a data member as if it were a method itself (that is, the Invoke method of its corresponding delegate). You must predefine the delegate type for declaring a managed event data member. In contrast, a managed event method implicitly defines the corresponding managed delegate if it is not already defined. See the code sample at the end of this topic for an example.

When declaring a managed event, you can specify add and remove accessors that will be called when event handlers are added or removed using operators += and -=. The add, remove and raise methods can be called explicitly.

The following steps must be taken in order to create and use events in Visual C++:

  1. Create or identify a delegate. If you are defining your own event, you must also ensure that there is a delegate to use with the event keyword. If the event is predefined, in the .NET Framework for example, then consumers of the event need only know the name of the delegate.

  2. Create a class that contains:

    • An event created from the delegate.

    • (optional) A method that verifies that an instance of the delegate declared with the event keyword exists. Otherwise, this logic must be placed in the code that fires the event.

    • Methods that call the event. These methods can be overrides of some base class functionality.

    This class defines the event.

  3. Define one or more classes that connect methods to the event. Each of these classes will associate one or more methods with the event in the base class.

  4. Use the event:

    • Create an object of the class that contains the event declaration.

    • Create an object of the class that contains the event definition.

event is a context-sensitive keyword; see Context-Sensitive Keywords for more information.

For more information on events, see

Example

// 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);
}
OnClick: 7, 3.14159
OnDblClick: Hello

The compiler uses the following logic to generate the raise method of a trivial event: If the event has one or more subscribers, calling the raise method implicitly or explicitly will call the delegate. If the delegate's return type is not void and if there are zero event subscribers, the raise method will return the default value for the delegate type. If there are no event subscribers, calling the raise method this will just return and no exception will be raised; if the delegate return type is not void, this will return the default value for the delegate type. For example

// 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);   
}
0
688

Requirements

Compiler option: /clr

See Also

Concepts

Language Features for Targeting the CLR