1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 namespace System.ComponentModel 6 { 7 /// <summary> 8 /// <para>Provides a simple list of delegates. This class cannot be inherited.</para> 9 /// </summary> 10 public sealed class EventHandlerList : IDisposable 11 { 12 private ListEntry _head; 13 private Component _parent; 14 15 /// <summary> 16 /// Creates a new event handler list. The parent component is used to check the component's 17 /// CanRaiseEvents property. 18 /// </summary> 19 internal EventHandlerList(Component parent) => _parent = parent; 20 21 /// <summary> 22 /// Creates a new event handler list. 23 /// </summary> EventHandlerList()24 public EventHandlerList() 25 { 26 } 27 28 /// <summary> 29 /// <para>Gets or sets the delegate for the specified key.</para> 30 /// </summary> 31 public Delegate this[object key] 32 { 33 get 34 { 35 ListEntry e = null; 36 if (_parent == null || _parent.CanRaiseEventsInternal) 37 { 38 e = Find(key); 39 } 40 41 return e?._handler; 42 } 43 set 44 { 45 ListEntry e = Find(key); 46 if (e != null) 47 { 48 e._handler = value; 49 } 50 else 51 { 52 _head = new ListEntry(key, value, _head); 53 } 54 } 55 } 56 57 /// <summary> 58 /// <para>[To be supplied.]</para> 59 /// </summary> AddHandler(object key, Delegate value)60 public void AddHandler(object key, Delegate value) 61 { 62 ListEntry e = Find(key); 63 if (e != null) 64 { 65 e._handler = Delegate.Combine(e._handler, value); 66 } 67 else 68 { 69 _head = new ListEntry(key, value, _head); 70 } 71 } 72 73 /// <summary> allows you to add a list of events to this list </summary> AddHandlers(EventHandlerList listToAddFrom)74 public void AddHandlers(EventHandlerList listToAddFrom) 75 { 76 ListEntry currentListEntry = listToAddFrom._head; 77 while (currentListEntry != null) 78 { 79 AddHandler(currentListEntry._key, currentListEntry._handler); 80 currentListEntry = currentListEntry._next; 81 } 82 } 83 Dispose()84 public void Dispose() => _head = null; 85 Find(object key)86 private ListEntry Find(object key) 87 { 88 ListEntry found = _head; 89 while (found != null) 90 { 91 if (found._key == key) 92 { 93 break; 94 } 95 found = found._next; 96 } 97 return found; 98 } 99 RemoveHandler(object key, Delegate value)100 public void RemoveHandler(object key, Delegate value) 101 { 102 ListEntry e = Find(key); 103 if (e != null) 104 { 105 e._handler = Delegate.Remove(e._handler, value); 106 } 107 // else... no error for removal of non-existent delegate 108 // 109 } 110 111 private sealed class ListEntry 112 { 113 internal ListEntry _next; 114 internal object _key; 115 internal Delegate _handler; 116 ListEntry(object key, Delegate handler, ListEntry next)117 public ListEntry(object key, Delegate handler, ListEntry next) 118 { 119 _next = next; 120 _key = key; 121 _handler = handler; 122 } 123 } 124 } 125 } 126