File: System\Windows\Forms\Design\EventHandlerService.cs
Web Access
Project: src\src\System.Windows.Forms.Design\src\System.Windows.Forms.Design.csproj (System.Windows.Forms.Design)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
namespace System.Windows.Forms.Design;
 
/// <summary>
///  Provides a systematic way to manage event handlers for the current document.
/// </summary>
public sealed class EventHandlerService : IEventHandlerService
{
    // We cache the last requested handler for speed.
    private object? _lastHandler;
    private Type? _lastHandlerType;
    private EventHandler? _changedEvent;
 
    private readonly LinkedList<object> _handlers = new();
 
    /// <summary>
    ///  Initializes a new instance of the EventHandlerService class.
    /// </summary>
    /// <param name="focusWnd">The <see cref="Control"/> which is being designed.</param>
    public EventHandlerService(Control? focusWnd)
    {
        FocusWindow = focusWnd;
    }
 
    /// <summary>
    ///  Fires an OnEventHandlerChanged event.
    /// </summary>
    public event EventHandler? EventHandlerChanged
    {
        add => _changedEvent += value;
        remove => _changedEvent -= value;
    }
 
    public Control? FocusWindow { get; }
 
    /// <summary>
    ///  Gets the currently active event handler of the specified type.
    /// </summary>
    public object? GetHandler(Type handlerType)
    {
        ArgumentNullException.ThrowIfNull(handlerType);
 
        if (_lastHandlerType is null)
        {
            return null;
        }
 
        if (handlerType == _lastHandlerType)
        {
            return _lastHandler;
        }
 
        Debug.Assert(_handlers.Count > 0, "Should have handlers to look through.");
 
        object? handler = _handlers.FirstOrDefault(handlerType.IsInstanceOfType);
 
        if (handler is not null)
        {
            _lastHandler = handler;
            _lastHandlerType = handlerType;
        }
 
        return handler;
    }
 
    /// <summary>
    ///  Pops the given handler off of the stack.
    /// </summary>
    public void PopHandler(object handler)
    {
        ArgumentNullException.ThrowIfNull(handler);
 
        if (_handlers.Remove(handler))
        {
            _lastHandler = null;
            _lastHandlerType = null;
            OnEventHandlerChanged(EventArgs.Empty);
        }
    }
 
    /// <summary>
    ///  Pushes a new event handler on the stack.
    /// </summary>
    public void PushHandler(object handler)
    {
        ArgumentNullException.ThrowIfNull(handler);
 
        _handlers.AddFirst(handler);
        _lastHandlerType = handler.GetType();
        _lastHandler = handler;
 
        OnEventHandlerChanged(EventArgs.Empty);
    }
 
    /// <summary>
    ///  Fires an OnEventHandlerChanged event.
    /// </summary>
    private void OnEventHandlerChanged(EventArgs e)
    {
        _changedEvent?.Invoke(this, e);
    }
}