|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace System.ComponentModel
{
/// <summary>
/// Provides a simple list of delegates. This class cannot be inherited.
/// </summary>
public sealed class EventHandlerList : IDisposable
{
private ListEntry? _head;
private readonly Component? _parent;
/// <summary>
/// Creates a new event handler list. The parent component is used to check the
/// component's CanRaiseEvents property.
/// </summary>
internal EventHandlerList(Component parent)
{
_parent = parent;
}
/// <summary>
/// Creates a new event handler list.
/// </summary>
public EventHandlerList()
{
}
/// <summary>
/// Gets or sets the delegate for the specified key.
/// </summary>
public Delegate? this[object key]
{
get
{
ListEntry? e = null;
if (_parent == null || _parent.CanRaiseEventsInternal)
{
e = Find(key);
}
return e?._handler;
}
set
{
ListEntry? e = Find(key);
if (e != null)
{
e._handler = value;
}
else
{
_head = new ListEntry(key, value, _head);
}
}
}
public void AddHandler(object key, Delegate? value)
{
ListEntry? e = Find(key);
if (e != null)
{
e._handler = Delegate.Combine(e._handler, value);
}
else
{
_head = new ListEntry(key, value, _head);
}
}
public void AddHandlers(EventHandlerList listToAddFrom)
{
ArgumentNullException.ThrowIfNull(listToAddFrom);
ListEntry? currentListEntry = listToAddFrom._head;
while (currentListEntry != null)
{
AddHandler(currentListEntry._key, currentListEntry._handler);
currentListEntry = currentListEntry._next;
}
}
public void Dispose() => _head = null;
private ListEntry? Find(object key)
{
ListEntry? found = _head;
while (found != null)
{
if (found._key == key)
{
break;
}
found = found._next;
}
return found;
}
public void RemoveHandler(object key, Delegate? value)
{
ListEntry? e = Find(key);
if (e != null)
{
e._handler = Delegate.Remove(e._handler, value);
}
}
private sealed class ListEntry
{
internal readonly ListEntry? _next;
internal readonly object _key;
internal Delegate? _handler;
public ListEntry(object key, Delegate? handler, ListEntry? next)
{
_next = next;
_key = key;
_handler = handler;
}
}
}
}
|