Практическое руководство. Обработка нескольких событий с помощью их свойств

Чтобы использовать свойства событий, следует определить свойства событий в классе, который вызывает события, а затем задать делегаты для свойств событий в классах, обрабатывающих события. Чтобы реализовать несколько свойств событий в классе, класс должен хранить и поддерживать делегат, определенный для каждого события. Для каждого события, аналогичного полю, создается соответствующий ссылочный тип резервного поля. Это может привести к ненужным выделениям при увеличении числа событий. В качестве альтернативы распространенный подход заключается в сохранении EventHandlerList событий по ключу.

Для сохранения делегатов для каждого события можно воспользоваться классом EventHandlerList или реализовать собственную коллекцию. Класс коллекции должен предоставить методы для установки, извлечения делегата обработчика событий и доступа к нему по ключу события. Например, можно использовать класс Hashtable или извлечь пользовательский класс от класса DictionaryBase. Сведения о реализации коллекции делегатов не обязательно предоставлять за пределами класса.

Каждое свойство события внутри класса определяет метод доступа add и remove. Метод доступа add для свойства события добавляет входной экземпляр делегата в коллекцию. Метод доступа remove для свойства события удаляет входной экземпляр делегата из коллекции. Методы доступа к свойствам событий используют предопределенный ключ для свойства события, чтобы добавлять экземпляры в коллекцию делегатов и удалять их из нее.

Обработка нескольких событий с помощью их свойств

  1. Определите коллекцию делегатов внутри класса, который вызывает события.

  2. Определите ключ для каждого события.

  3. Определите свойства событий в классе, который вызывает события.

  4. Используйте коллекцию делегатов для реализации методов доступа add и remove для свойств событий.

  5. Используйте открытые свойства событий делегатов обработчика событий добавления и удаления в классах, обрабатывающих эти события.

Пример

В следующем примере 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

См. также