2 // System.Web.UI.ControlCollection.cs
5 // Duncan Mak (duncan@ximian.com)
6 // Gonzalo Paniagua Javier (gonzalo@novell.com)
8 // Copyright (c) 2002-2005 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");
62 public bool IsReadOnly {
63 get { return readOnly; }
66 public bool IsSynchronized {
70 public virtual Control this [int index] {
72 if (index < 0 || index >= count)
73 throw new ArgumentOutOfRangeException ("index");
75 return controls [index];
79 protected Control Owner {
83 public object SyncRoot {
87 void EnsureControls ()
89 if (controls == null) {
90 controls = new Control [5];
91 } else if (controls.Length < count + 1) {
92 int n = controls.Length == 5 ? 3 : 2;
93 Control [] newControls = new Control [controls.Length * n];
94 Array.Copy (controls, 0, newControls, 0, controls.Length);
95 controls = newControls;
99 public virtual void Add (Control child)
102 throw new ArgumentNullException ("child");
105 throw new HttpException (Locale.GetText ("Collection is read-only."));
107 if (Object.ReferenceEquals (owner, child))
108 throw new HttpException (Locale.GetText ("Cannot add collection's owner."));
112 controls [count++] = child;
113 owner.AddedControl (child, count - 1);
116 public virtual void AddAt (int index, Control child)
118 if (child == null) // maybe we should check for ! (child is Control)?
119 throw new ArgumentNullException ();
121 if (index < -1 || index > count)
122 throw new ArgumentOutOfRangeException ();
125 throw new HttpException (Locale.GetText ("Collection is read-only."));
127 if (Object.ReferenceEquals (owner, child))
128 throw new HttpException (Locale.GetText ("Cannot add collection's owner."));
137 Array.Copy (controls, index, controls, index + 1, count - index);
139 controls [index] = child;
140 owner.AddedControl (child, index);
143 public virtual void Clear ()
145 if (controls == null)
149 for (int i = 0; i < count; i++)
150 owner.RemovedControl (controls [i]);
154 owner.ResetChildNames ();
157 public virtual bool Contains (Control c)
159 return (controls != null && Array.IndexOf (controls, c) != -1);
166 void CopyTo (Array array, int index)
168 if (controls == null)
171 // can't use controls.CopyTo (array, index);
172 // as we do not allocate it based on the true
173 // numbers of items we have in the collection
174 // so we must re-implement Array.CopyTo :(
177 throw new ArgumentNullException ("array");
178 if (index + count > array.GetLowerBound (0) + array.GetLength (0))
179 throw new ArgumentException ();
181 throw new RankException (Locale.GetText ("Only single dimension arrays are supported."));
183 throw new ArgumentOutOfRangeException ("index", Locale.GetText ("Value has to be >= 0."));
185 for (int i=0; i < count; i++)
186 array.SetValue (controls [i], i + index);
193 IEnumerator GetEnumerator ()
195 return new SimpleEnumerator (this);
198 public virtual int IndexOf (Control c)
200 if (controls == null || c == null)
203 return Array.IndexOf (controls, c);
206 public virtual void Remove (Control value)
208 int idx = IndexOf (value);
214 public virtual void RemoveAt (int index)
217 throw new HttpException ();
220 Control ctrl = controls [index];
222 if (count - index > 0)
223 Array.Copy (controls, index + 1, controls, index, count - index);
225 controls [count] = null;
226 owner.RemovedControl (ctrl);
229 internal void SetReadonly (bool readOnly)
231 this.readOnly = readOnly;
234 // Almost the same as in ArrayList
235 sealed class SimpleEnumerator : IEnumerator
237 ControlCollection coll;
240 object currentElement;
242 public SimpleEnumerator (ControlCollection coll)
246 version = coll.version;
249 public bool MoveNext ()
251 if (version != coll.version)
252 throw new InvalidOperationException ("List has changed.");
254 if (index >= -1 && ++index < coll.Count) {
255 currentElement = coll [index];
263 public object Current {
266 throw new InvalidOperationException (index == -1 ? "Enumerator not started" : "Enumerator ended");
268 return currentElement;
274 if (version != coll.version)
275 throw new InvalidOperationException ("List has changed.");