ControlCollection.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. //
  2. // System.Web.UI.ControlCollection.cs
  3. //
  4. // Authors:
  5. // Duncan Mak ([email protected])
  6. // Gonzalo Paniagua Javier ([email protected])
  7. //
  8. // Copyright (c) 2002-2005 Novell, Inc. (http://www.novell.com)
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining
  11. // a copy of this software and associated documentation files (the
  12. // "Software"), to deal in the Software without restriction, including
  13. // without limitation the rights to use, copy, modify, merge, publish,
  14. // distribute, sublicense, and/or sell copies of the Software, and to
  15. // permit persons to whom the Software is furnished to do so, subject to
  16. // the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. //
  29. using System.Collections;
  30. using System.Security.Permissions;
  31. namespace System.Web.UI {
  32. // CAS
  33. [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  34. [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  35. public class ControlCollection : ICollection, IEnumerable
  36. {
  37. Control owner;
  38. Control [] controls;
  39. int version;
  40. int count;
  41. bool readOnly;
  42. public ControlCollection (Control owner)
  43. {
  44. if (owner == null)
  45. throw new ArgumentException ("owner");
  46. this.owner = owner;
  47. }
  48. public
  49. #if NET_2_0
  50. virtual
  51. #endif
  52. int Count {
  53. get { return count; }
  54. }
  55. public bool IsReadOnly {
  56. get { return readOnly; }
  57. }
  58. public bool IsSynchronized {
  59. get { return false; }
  60. }
  61. public virtual Control this [int index] {
  62. get {
  63. if (index < 0 || index >= count)
  64. throw new ArgumentOutOfRangeException ("index");
  65. return controls [index];
  66. }
  67. }
  68. protected Control Owner {
  69. get { return owner; }
  70. }
  71. public object SyncRoot {
  72. get { return this; }
  73. }
  74. void EnsureControls ()
  75. {
  76. if (controls == null) {
  77. controls = new Control [5];
  78. } else if (controls.Length < count + 1) {
  79. int n = controls.Length == 5 ? 3 : 2;
  80. Control [] newControls = new Control [controls.Length * n];
  81. Array.Copy (controls, 0, newControls, 0, controls.Length);
  82. controls = newControls;
  83. }
  84. }
  85. public virtual void Add (Control child)
  86. {
  87. if (child == null)
  88. throw new ArgumentNullException ("child");
  89. if (readOnly)
  90. throw new HttpException (Locale.GetText ("Collection is read-only."));
  91. if (Object.ReferenceEquals (owner, child))
  92. throw new HttpException (Locale.GetText ("Cannot add collection's owner."));
  93. EnsureControls ();
  94. version++;
  95. controls [count++] = child;
  96. owner.AddedControl (child, count - 1);
  97. }
  98. public virtual void AddAt (int index, Control child)
  99. {
  100. if (child == null) // maybe we should check for ! (child is Control)?
  101. throw new ArgumentNullException ();
  102. if (index < -1 || index > count)
  103. throw new ArgumentOutOfRangeException ();
  104. if (readOnly)
  105. throw new HttpException (Locale.GetText ("Collection is read-only."));
  106. if (Object.ReferenceEquals (owner, child))
  107. throw new HttpException (Locale.GetText ("Cannot add collection's owner."));
  108. if (index == -1) {
  109. Add (child);
  110. return;
  111. }
  112. EnsureControls ();
  113. version++;
  114. Array.Copy (controls, index, controls, index + 1, count - index);
  115. count++;
  116. controls [index] = child;
  117. owner.AddedControl (child, index);
  118. }
  119. public virtual void Clear ()
  120. {
  121. if (controls == null)
  122. return;
  123. version++;
  124. for (int i = 0; i < count; i++)
  125. owner.RemovedControl (controls [i]);
  126. count = 0;
  127. if (owner != null)
  128. owner.ResetChildNames ();
  129. }
  130. public virtual bool Contains (Control c)
  131. {
  132. return (controls != null && Array.IndexOf (controls, c) != -1);
  133. }
  134. public
  135. #if NET_2_0
  136. virtual
  137. #endif
  138. void CopyTo (Array array, int index)
  139. {
  140. if (controls == null)
  141. return;
  142. // can't use controls.CopyTo (array, index);
  143. // as we do not allocate it based on the true
  144. // numbers of items we have in the collection
  145. // so we must re-implement Array.CopyTo :(
  146. if (array == null)
  147. throw new ArgumentNullException ("array");
  148. if (index + count > array.GetLowerBound (0) + array.GetLength (0))
  149. throw new ArgumentException ();
  150. if (array.Rank > 1)
  151. throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
  152. if (index < 0)
  153. throw new ArgumentOutOfRangeException ("index", Locale.GetText ("Value has to be >= 0."));
  154. for (int i=0; i < count; i++)
  155. array.SetValue (controls [i], i);
  156. }
  157. public
  158. #if NET_2_0
  159. virtual
  160. #endif
  161. IEnumerator GetEnumerator ()
  162. {
  163. return new SimpleEnumerator (this);
  164. }
  165. public virtual int IndexOf (Control c)
  166. {
  167. if (controls == null || c == null)
  168. return -1;
  169. return Array.IndexOf (controls, c);
  170. }
  171. public virtual void Remove (Control value)
  172. {
  173. int idx = IndexOf (value);
  174. if (idx == -1)
  175. return;
  176. RemoveAt (idx);
  177. }
  178. public virtual void RemoveAt (int index)
  179. {
  180. if (readOnly)
  181. throw new HttpException ();
  182. version++;
  183. Control ctrl = controls [index];
  184. count--;
  185. if (count - index > 0)
  186. Array.Copy (controls, index + 1, controls, index, count - index);
  187. controls [count] = null;
  188. owner.RemovedControl (ctrl);
  189. }
  190. internal void SetReadonly (bool readOnly)
  191. {
  192. this.readOnly = readOnly;
  193. }
  194. // Almost the same as in ArrayList
  195. sealed class SimpleEnumerator : IEnumerator
  196. {
  197. ControlCollection coll;
  198. int index;
  199. int version;
  200. object currentElement;
  201. public SimpleEnumerator (ControlCollection coll)
  202. {
  203. this.coll = coll;
  204. index = -1;
  205. version = coll.version;
  206. }
  207. public bool MoveNext ()
  208. {
  209. if (version != coll.version)
  210. throw new InvalidOperationException ("List has changed.");
  211. if (index >= -1 && ++index < coll.Count) {
  212. currentElement = coll [index];
  213. return true;
  214. } else {
  215. index = -2;
  216. return false;
  217. }
  218. }
  219. public object Current {
  220. get {
  221. if (index < 0)
  222. throw new InvalidOperationException (index == -1 ? "Enumerator not started" : "Enumerator ended");
  223. return currentElement;
  224. }
  225. }
  226. public void Reset ()
  227. {
  228. if (version != coll.version)
  229. throw new InvalidOperationException ("List has changed.");
  230. index = -1;
  231. }
  232. }
  233. }
  234. }