How to: Handle Multiple Events Using Event Properties
To use event properties, you define the event properties in the class that raises the events, and then set the delegates for the event properties in classes that handle the events. To implement multiple event properties in a class, the class should internally store and maintain the delegate defined for each event. For each field-like-event, a corresponding backing-field reference type is generated. This can lead to unnecessary allocations when the number of events increases. As an alternative, a common approach is to maintain an EventHandlerList which stores events by key.
To store the delegates for each event, you can use the EventHandlerList class, or implement your own collection. The collection class must provide methods for setting, accessing, and retrieving the event handler delegate based on the event key. For example, you could use a Hashtable class, or derive a custom class from the DictionaryBase class. The implementation details of the delegate collection do not need to be exposed outside your class.
Each event property within the class defines an add accessor method and a remove accessor method. The add accessor for an event property adds the input delegate instance to the delegate collection. The remove accessor for an event property removes the input delegate instance from the delegate collection. The event property accessors use the predefined key for the event property to add and remove instances from the delegate collection.
To handle multiple events using event properties
Define a delegate collection within the class that raises the events.
Define a key for each event.
Define the event properties in the class that raises the events.
Use the delegate collection to implement the add and remove accessor methods for the event properties.
Use the public event properties to add and remove event handler delegates in the classes that handle the events.
Example
The following C# example implements the event properties MouseDown
and MouseUp
, using an EventHandlerList to store each event's delegate. The keywords of the event property constructs are in bold type.
// The class SampleControl defines two event properties, MouseUp and MouseDown.
ref class SampleControl : Component
{
// :
// Define other control methods and properties.
// :
// Define the delegate collection.
protected:
EventHandlerList^ listEventDelegates;
private:
// Define a unique key for each event.
static Object^ mouseDownEventKey = gcnew Object();
static Object^ mouseUpEventKey = gcnew Object();
// Define the MouseDown event property.
public:
SampleControl()
{
listEventDelegates = gcnew EventHandlerList();
}
event MouseEventHandler^ MouseDown
{
// Add the input delegate to the collection.
void add(MouseEventHandler^ value)
{
listEventDelegates->AddHandler(mouseDownEventKey, value);
}
// Remove the input delegate from the collection.
void remove(MouseEventHandler^ value)
{
listEventDelegates->RemoveHandler(mouseDownEventKey, value);
}
// Raise the event with the delegate specified by mouseDownEventKey
void raise(Object^ sender, MouseEventArgs^ e)
{
MouseEventHandler^ mouseEventDelegate =
(MouseEventHandler^)listEventDelegates[mouseDownEventKey];
mouseEventDelegate(sender, e);
}
}
// Define the MouseUp event property.
event MouseEventHandler^ MouseUp
{
// Add the input delegate to the collection.
void add(MouseEventHandler^ value)
{
listEventDelegates->AddHandler(mouseUpEventKey, value);
}
// Remove the input delegate from the collection.
void remove(MouseEventHandler^ value)
{
listEventDelegates->RemoveHandler(mouseUpEventKey, value);
}
// Raise the event with the delegate specified by mouseUpEventKey
void raise(Object^ sender, MouseEventArgs^ e)
{
MouseEventHandler^ mouseEventDelegate =
(MouseEventHandler^)listEventDelegates[mouseUpEventKey];
mouseEventDelegate(sender, e);
}
}
};
// The class SampleControl defines two event properties, MouseUp and MouseDown.
class SampleControl : Component
{
// :
// Define other control methods and properties.
// :
// Define the delegate collection.
protected EventHandlerList listEventDelegates = new EventHandlerList();
// Define a unique key for each event.
static readonly object mouseDownEventKey = new object();
static readonly object mouseUpEventKey = new object();
// Define the MouseDown event property.
public event MouseEventHandler MouseDown
{
// Add the input delegate to the collection.
add
{
listEventDelegates.AddHandler(mouseDownEventKey, value);
}
// Remove the input delegate from the collection.
remove
{
listEventDelegates.RemoveHandler(mouseDownEventKey, value);
}
}
// Raise the event with the delegate specified by mouseDownEventKey
private void OnMouseDown(MouseEventArgs e)
{
MouseEventHandler mouseEventDelegate =
(MouseEventHandler)listEventDelegates[mouseDownEventKey];
mouseEventDelegate(this, e);
}
// Define the MouseUp event property.
public event MouseEventHandler MouseUp
{
// Add the input delegate to the collection.
add
{
listEventDelegates.AddHandler(mouseUpEventKey, value);
}
// Remove the input delegate from the collection.
remove
{
listEventDelegates.RemoveHandler(mouseUpEventKey, value);
}
}
// Raise the event with the delegate specified by mouseUpEventKey
private void OnMouseUp(MouseEventArgs e)
{
MouseEventHandler mouseEventDelegate =
(MouseEventHandler)listEventDelegates[mouseUpEventKey];
mouseEventDelegate(this, e);
}
}
' The class SampleControl defines two event properties, MouseUp and MouseDown.
Class SampleControl
Inherits Component
' :
' Define other control methods and properties.
' :
' Define the delegate collection.
Protected listEventDelegates As New EventHandlerList()
' Define a unique key for each event.
Shared ReadOnly mouseDownEventKey As New Object()
Shared ReadOnly mouseUpEventKey As New Object()
' Define the MouseDown event property.
Public Custom Event MouseDown As MouseEventHandler
' Add the input delegate to the collection.
AddHandler(Value As MouseEventHandler)
listEventDelegates.AddHandler(mouseDownEventKey, Value)
End AddHandler
' Remove the input delegate from the collection.
RemoveHandler(Value As MouseEventHandler)
listEventDelegates.RemoveHandler(mouseDownEventKey, Value)
End RemoveHandler
' Raise the event with the delegate specified by mouseDownEventKey
RaiseEvent(sender As Object, e As MouseEventArgs)
Dim mouseEventDelegate As MouseEventHandler = _
listEventDelegates(mouseDownEventKey)
mouseEventDelegate(sender, e)
End RaiseEvent
End Event
' Define the MouseUp event property.
Public Custom Event MouseUp As MouseEventHandler
' Add the input delegate to the collection.
AddHandler(Value As MouseEventHandler)
listEventDelegates.AddHandler(mouseUpEventKey, Value)
End AddHandler
' Remove the input delegate from the collection.
RemoveHandler(Value As MouseEventHandler)
listEventDelegates.RemoveHandler(mouseUpEventKey, Value)
End RemoveHandler
' Raise the event with the delegate specified by mouseDownUpKey
RaiseEvent(sender As Object, e As MouseEventArgs)
Dim mouseEventDelegate As MouseEventHandler = _
listEventDelegates(mouseUpEventKey)
mouseEventDelegate(sender, e)
End RaiseEvent
End Event
End Class