Практическое руководство. Обработка нескольких событий с помощью их свойств
Чтобы использовать свойства событий, следует определить свойства событий в классе, который вызывает события, а затем задать делегаты для свойств событий в классах, обрабатывающих события. Чтобы реализовать несколько свойств событий в классе, класс должен хранить и поддерживать делегат, определенный для каждого события. Для каждого события, аналогичного полю, создается соответствующий ссылочный тип резервного поля. Это может привести к ненужным выделениям при увеличении числа событий. В качестве альтернативы распространенный подход заключается в сохранении EventHandlerList событий по ключу.
Для сохранения делегатов для каждого события можно воспользоваться классом EventHandlerList или реализовать собственную коллекцию. Класс коллекции должен предоставить методы для установки, извлечения делегата обработчика событий и доступа к нему по ключу события. Например, можно использовать класс Hashtable или извлечь пользовательский класс от класса DictionaryBase. Сведения о реализации коллекции делегатов не обязательно предоставлять за пределами класса.
Каждое свойство события внутри класса определяет метод доступа add и remove. Метод доступа add для свойства события добавляет входной экземпляр делегата в коллекцию. Метод доступа remove для свойства события удаляет входной экземпляр делегата из коллекции. Методы доступа к свойствам событий используют предопределенный ключ для свойства события, чтобы добавлять экземпляры в коллекцию делегатов и удалять их из нее.
Обработка нескольких событий с помощью их свойств
Определите коллекцию делегатов внутри класса, который вызывает события.
Определите ключ для каждого события.
Определите свойства событий в классе, который вызывает события.
Используйте коллекцию делегатов для реализации методов доступа add и remove для свойств событий.
Используйте открытые свойства событий делегатов обработчика событий добавления и удаления в классах, обрабатывающих эти события.
Пример
В следующем примере C# реализуются свойства событий MouseDown
и MouseUp
с использованием объекта EventHandlerList для хранения делегата каждого события. Ключевые слова для конструкции свойств событий выделены жирным шрифтом.
// 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