2 // System.Web.UI.ControlCollection.cs
5 // Duncan Mak (duncan@ximian.com)
6 // Gonzalo Paniagua Javier (gonzalo@novell.com)
8 // Copyright (c) 2002-2010 Novell, Inc. (http://www.novell.com)
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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.
30 using System.Collections;
31 using System.Security.Permissions;
33 namespace System.Web.UI {
36 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
37 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
38 public class ControlCollection : ICollection, IEnumerable
46 public ControlCollection (Control owner)
49 throw new ArgumentException ("owner");
54 public virtual int Count {
58 public bool IsReadOnly {
59 get { return readOnly; }
62 public bool IsSynchronized {
66 public virtual Control this [int index] {
68 if (index < 0 || index >= count)
69 throw new ArgumentOutOfRangeException ("index");
71 return controls [index];
75 protected Control Owner {
79 public object SyncRoot {
83 void EnsureControls ()
85 if (controls == null) {
86 controls = new Control [5];
87 } else if (controls.Length < count + 1) {
88 int n = controls.Length == 5 ? 3 : 2;
89 Control [] newControls = new Control [controls.Length * n];
90 Array.Copy (controls, 0, newControls, 0, controls.Length);
91 controls = newControls;
95 public virtual void Add (Control child)
98 throw new ArgumentNullException ("child");
101 throw new HttpException (Locale.GetText ("Collection is read-only."));
103 if (Object.ReferenceEquals (owner, child))
104 throw new HttpException (Locale.GetText ("Cannot add collection's owner."));
108 controls [count++] = child;
109 owner.AddedControl (child, count - 1);
112 public virtual void AddAt (int index, Control child)
114 if (child == null) // maybe we should check for ! (child is Control)?
115 throw new ArgumentNullException ();
117 if (index < -1 || index > count)
118 throw new ArgumentOutOfRangeException ();
121 throw new HttpException (Locale.GetText ("Collection is read-only."));
123 if (Object.ReferenceEquals (owner, child))
124 throw new HttpException (Locale.GetText ("Cannot add collection's owner."));
133 Array.Copy (controls, index, controls, index + 1, count - index);
135 controls [index] = child;
136 owner.AddedControl (child, index);
139 public virtual void Clear ()
141 if (controls == null)
145 for (int i = 0; i < count; i++)
146 owner.RemovedControl (controls [i]);
150 owner.ResetChildNames ();
153 public virtual bool Contains (Control c)
155 return (controls != null && Array.IndexOf (controls, c) != -1);
158 public virtual void CopyTo (Array array, int index)
160 if (controls == null)
163 // can't use controls.CopyTo (array, index);
164 // as we do not allocate it based on the true
165 // numbers of items we have in the collection
166 // so we must re-implement Array.CopyTo :(
169 throw new ArgumentNullException ("array");
170 if (index + count > array.GetLowerBound (0) + array.GetLength (0))
171 throw new ArgumentException ();
173 throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
175 throw new ArgumentOutOfRangeException ("index", Locale.GetText ("Value has to be >= 0."));
177 for (int i=0; i < count; i++)
178 array.SetValue (controls [i], i + index);
181 public virtual IEnumerator GetEnumerator ()
183 return new SimpleEnumerator (this);
186 public virtual int IndexOf (Control c)
188 if (controls == null || c == null)
191 return Array.IndexOf (controls, c);
194 public virtual void Remove (Control value)
196 int idx = IndexOf (value);
202 public virtual void RemoveAt (int index)
205 throw new HttpException ();
208 Control ctrl = controls [index];
210 if (count - index > 0)
211 Array.Copy (controls, index + 1, controls, index, count - index);
213 controls [count] = null;
214 owner.RemovedControl (ctrl);
217 internal void SetReadonly (bool readOnly)
219 this.readOnly = readOnly;
222 // Almost the same as in ArrayList
223 sealed class SimpleEnumerator : IEnumerator
225 ControlCollection coll;
228 object currentElement;
230 public SimpleEnumerator (ControlCollection coll)
234 version = coll.version;
237 public bool MoveNext ()
239 if (version != coll.version)
240 throw new InvalidOperationException ("List has changed.");
242 if (index >= -1 && ++index < coll.Count) {
243 currentElement = coll [index];
251 public object Current {
254 throw new InvalidOperationException (index == -1 ? "Enumerator not started" : "Enumerator ended");
256 return currentElement;
262 if (version != coll.version)
263 throw new InvalidOperationException ("List has changed.");