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