2004-11-09 Gonzalo Paniagua Javier <gonzalo@ximian.com>
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Tue, 9 Nov 2004 17:03:26 +0000 (17:03 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Tue, 9 Nov 2004 17:03:26 +0000 (17:03 -0000)
* Control.cs: unified a few bool fields into an int one.

* ControlCollection.cs: use an array internally instead of always
allocating an arraylist. Also added our own enumerator.

* EmptyControlCollection.cs: there's no 'special' ctor now in the base
class.

svn path=/trunk/mcs/; revision=35900

mcs/class/System.Web/System.Web.UI/ChangeLog
mcs/class/System.Web/System.Web.UI/Control.cs
mcs/class/System.Web/System.Web.UI/ControlCollection.cs
mcs/class/System.Web/System.Web.UI/EmptyControlCollection.cs

index 4a2f25b6c40a5adde96371643fd4690c9cc88a24..34d2291f00da083404b667b23919d0f87c3271ec 100644 (file)
@@ -1,3 +1,13 @@
+2004-11-09 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * Control.cs: unified a few bool fields into an int one.
+
+       * ControlCollection.cs: use an array internally instead of always
+       allocating an arraylist. Also added our own enumerator.
+       
+       * EmptyControlCollection.cs: there's no 'special' ctor now in the base
+       class.
+
 2004-11-05 Sanjay Gupta <gsanjay@novell.com>
 
        * DataSourceView.cs: Changes in access modifiers of methods.
index 40eda9225592a0b2940b7a393622f83636be4b3f..3df53698b28a4eb52069efa3009e825733b93b57 100644 (file)
@@ -46,53 +46,59 @@ namespace System.Web.UI
        [DefaultProperty ("ID"), DesignerCategory ("Code"), ToolboxItemFilter ("System.Web.UI", ToolboxItemFilterType.Require)]
        [ToolboxItem ("System.Web.UI.Design.WebControlToolboxItem, " + Consts.AssemblySystem_Design)]
        [Designer ("System.Web.UI.Design.ControlDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
-       [DesignerSerializer ("Microsoft.VSDesigner.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
+       [DesignerSerializer ("Microsoft.VSDesigner.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VSDesigner,
+                               "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
         public class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor
 #if NET_2_0
         , IUrlResolutionService, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor
 #endif
         {
-               private static readonly object DataBindingEvent = new object();
-               private static readonly object DisposedEvent = new object();
-               private static readonly object InitEvent = new object();
-               private static readonly object LoadEvent = new object();
-               private static readonly object PreRenderEvent = new object();
-               private static readonly object UnloadEvent = new object();
-               private static string[] defaultNameArray;
-               private string _templateSourceDir;
-               private string uniqueID;
-               private string _userId;
-               private bool id_set;
-               private ControlCollection _controls;
-               private bool _enableViewState = true;
-               private IDictionary _childViewStates;
-               private bool _isNamingContainer;
-               private Control _namingContainer;
-               private Page _page;
-               private Control _parent;
-               private ISite _site;
-               private bool _visible = true;
-               private bool visibleChanged;
-               private HttpContext _context;
-               private bool _childControlsCreated;
-               private StateBag _viewState;
-               private bool _trackViewState;
-               private EventHandlerList _events;
-               private RenderMethod _renderMethodDelegate;
-               private bool autoID = true;
-               private bool creatingControls;
-               private bool bindingContainer = true;
-               private bool autoEventWireup = true;
-
-               bool inited, initing;
-               bool viewStateLoaded;
-               bool loaded;
-               bool prerendered;
+               static readonly object DataBindingEvent = new object();
+               static readonly object DisposedEvent = new object();
+               static readonly object InitEvent = new object();
+               static readonly object LoadEvent = new object();
+               static readonly object PreRenderEvent = new object();
+               static readonly object UnloadEvent = new object();
+               static string[] defaultNameArray;
+
+               string uniqueID;
+               string _userId;
+               ControlCollection _controls;
+               IDictionary _childViewStates;
+               Control _namingContainer;
+               Page _page;
+               Control _parent;
+               ISite _site;
+               HttpContext _context;
+               StateBag _viewState;
+               EventHandlerList _events;
+               RenderMethod _renderMethodDelegate;
                int defaultNumberID;
  
                DataBindingCollection dataBindings;
                Hashtable pendingVS; // may hold unused viewstate data from child controls
                
+
+               /*************/
+               int stateMask;
+               const int ENABLE_VIEWSTATE      = 1;
+               const int VISIBLE               = 1 << 1;
+               const int AUTOID                = 1 << 2;
+               const int CREATING_CONTROLS     = 1 << 3;
+               const int BINDING_CONTAINER     = 1 << 4;
+               const int AUTO_EVENT_WIREUP     = 1 << 5;
+               const int IS_NAMING_CONTAINER   = 1 << 6;
+               const int VISIBLE_CHANGED       = 1 << 7;
+               const int TRACK_VIEWSTATE       = 1 << 8;
+               const int CHILD_CONTROLS_CREATED = 1 << 9;
+               const int ID_SET                = 1 << 10;
+               const int INITED                = 1 << 11;
+               const int INITING               = 1 << 12;
+               const int VIEWSTATE_LOADED      = 1 << 13;
+               const int LOADED                = 1 << 14;
+               const int PRERENDERED           = 1 << 15;
+               /*************/
+               
                static Control ()
                {
                        defaultNameArray = new string [100];
@@ -100,23 +106,24 @@ namespace System.Web.UI
                                defaultNameArray [i] = "_ctrl" + i;
                }
 
-                public Control()\r
-                {\r
-                        if (this is INamingContainer) _isNamingContainer = true;\r
-                }\r
+                public Control()
+                {
+                       stateMask = ENABLE_VIEWSTATE | VISIBLE | AUTOID | BINDING_CONTAINER | AUTO_EVENT_WIREUP;
+                        if (this is INamingContainer)
+                               stateMask |= IS_NAMING_CONTAINER;
+                }
 
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]\r
-               public Control BindingContainer\r
-               {\r
-                       get {\r
-                               Control container = NamingContainer;\r
-                               if (!container.bindingContainer)\r
-                                       container = container.BindingContainer;\r
-                               return container;\r
-                       }\r
-               }\r
-               
+               public Control BindingContainer {
+                       get {
+                               Control container = NamingContainer;
+                               if ((container.stateMask & BINDING_CONTAINER) == 0)
+                                       container = container.BindingContainer;
+                               return container;
+                       }
+               }
+
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                [Browsable (false)]
                [WebSysDescription ("An Identification of the control that is rendered.")]\r
@@ -148,17 +155,10 @@ namespace System.Web.UI
 #if NET_2_0
                [Themeable (true)]
 #endif                
-                public virtual bool EnableViewState //DIT\r
-                {\r
-                        get\r
-                        {\r
-                                return _enableViewState;\r
-                        }\r
-                        set\r
-                        {\r
-                                _enableViewState = value;\r
-                        }\r
-                }\r
+                public virtual bool EnableViewState {
+                        get { return ((stateMask & ENABLE_VIEWSTATE) != 0); }
+                       set { SetMask (ENABLE_VIEWSTATE, value); }
+                }
                
                [MergableProperty (false), ParenthesizePropertyName (true)]
                [WebSysDescription ("The name of the control that is rendered.")]\r
@@ -168,14 +168,14 @@ namespace System.Web.UI
 
                 public virtual string ID {\r
                         get {\r
-                               return (id_set ? _userId : null);
+                               return (((stateMask & ID_SET) != 0) ? _userId : null);
                         }\r
                        \r
                         set {\r
                                if (value == "")\r
                                        value = null;\r
 \r
-                               id_set = true;
+                               stateMask |= ID_SET;
                                 _userId = value;\r
                                NullifyUniqueID ();\r
                         }\r
@@ -184,18 +184,16 @@ namespace System.Web.UI
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                [Browsable (false)]
                [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]\r
-                public virtual Control NamingContainer //DIT\r
-                {\r
-                        get\r
-                        {\r
-                                if (_namingContainer == null && _parent != null)\r
-                                {\r
-                                        if (_parent._isNamingContainer == false)\r
-                                                _namingContainer = _parent.NamingContainer;\r
-                                        else\r
-                                                _namingContainer = _parent;\r
-                                }\r
-                                return _namingContainer;\r
+                public virtual Control NamingContainer {
+                        get {
+                                if (_namingContainer == null && _parent != null) {
+                                        if ((_parent.stateMask & IS_NAMING_CONTAINER) == 0)
+                                                _namingContainer = _parent.NamingContainer;
+                                        else
+                                                _namingContainer = _parent;
+                                }
+
+                                return _namingContainer;
                         }\r
                 }
 
@@ -277,6 +275,14 @@ namespace System.Web.UI
                         }\r
                 }
 
+               void SetMask (int m, bool val)
+               {
+                       if (val)
+                               stateMask |= m;
+                       else
+                               stateMask &= ~m;
+               }
+               
                [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
                [WebSysDescription ("Visiblity state of the control.")]
 #if NET_2_0
@@ -284,7 +290,7 @@ namespace System.Web.UI
 #endif
                 public virtual bool Visible {
                         get {
-                               if (_visible == false)
+                               if ((stateMask & VISIBLE) == 0)
                                        return false;
 
                                if (_parent != null)
@@ -294,28 +300,25 @@ namespace System.Web.UI
                         }
 
                         set {
-                               if (value != _visible) {
+                               if ((value && (stateMask & VISIBLE) == 0) ||
+                                   (!value && (stateMask & VISIBLE) != 0)) {
                                        if (IsTrackingViewState)
-                                               visibleChanged = true;
+                                               stateMask |= VISIBLE_CHANGED;
                                }
 
-                                _visible = value;
+                               SetMask (VISIBLE, value);
                         }
                 }
 
-                protected bool ChildControlsCreated //DIT\r
-                {\r
-                        get\r
-                        {\r
-                                return _childControlsCreated;\r
-                        }\r
-                        set\r
-                        {\r
-                                if (value == false && _childControlsCreated == true)\r
-                                        Controls.Clear();
-                                _childControlsCreated = value;\r
-                        }\r
-                }\r
+                protected bool ChildControlsCreated {
+                        get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
+                        set {
+                               if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0)
+                                       Controls.Clear();
+
+                               SetMask (CHILD_CONTROLS_CREATED, value);
+                        }
+                }
 
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
@@ -353,13 +356,10 @@ namespace System.Web.UI
                                 return true;\r
                         }\r
                 }\r
-                protected bool IsTrackingViewState //DIT\r
-                {\r
-                        get\r
-                        {\r
-                                return _trackViewState;\r
-                        }\r
-                }\r
+
+                protected bool IsTrackingViewState {\r
+                        get { return ((stateMask & TRACK_VIEWSTATE) != 0); }
+                }
 
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
@@ -387,16 +387,16 @@ namespace System.Web.UI
                         }\r
                 }\r
 \r
-               internal bool AutoEventWireup {\r
-                       get { return autoEventWireup; }\r
-                       set { autoEventWireup = value; }\r
-               }\r
-\r
-               internal void SetBindingContainer (bool isBC)\r
-               {\r
-                       bindingContainer = isBC;\r
-               }\r
-               \r
+               internal bool AutoEventWireup {
+                       get { return (stateMask & AUTO_EVENT_WIREUP) != 0; }
+                       set { SetMask (AUTO_EVENT_WIREUP, value); }
+               }
+
+               internal void SetBindingContainer (bool isBC)
+               {
+                       SetMask (BINDING_CONTAINER, isBC);
+               }
+
                internal void ResetChildNames ()\r
                {\r
                        defaultNumberID = 0;\r
@@ -431,7 +431,7 @@ namespace System.Web.UI
 
                        control._parent = this;
                        control._page = _page;
-                       Control nc = _isNamingContainer ? this : NamingContainer;
+                       Control nc = ((stateMask & IS_NAMING_CONTAINER) != 0) ? this : NamingContainer;
 
                        if (nc != null) {
                                control._namingContainer = nc;
@@ -439,10 +439,10 @@ namespace System.Web.UI
                                        control._userId =  nc.GetDefaultName () + "a";
                        }
 
-                       if (initing || inited)
+                       if ((stateMask & (INITING | INITED)) != 0)
                                control.InitRecursive (nc);
 
-                       if (viewStateLoaded || loaded) {
+                       if ((stateMask & (VIEWSTATE_LOADED | LOADED)) != 0) {
                                if (pendingVS != null) {
                                        object vs = pendingVS [index];
                                        if (vs != null) {
@@ -455,10 +455,10 @@ namespace System.Web.UI
                                }
                        }
 
-                       if (loaded)
+                       if ((stateMask & LOADED) != 0)
                                control.LoadRecursive ();
                        
-                       if (prerendered)
+                       if ((stateMask & PRERENDERED) != 0)
                                control.PreRenderRecursiveInternal ();
                }
 
@@ -488,14 +488,14 @@ namespace System.Web.UI
                         return new ControlCollection(this);\r
                 }\r
 \r
-                protected virtual void EnsureChildControls () //DIT\r
-                {\r
-                        if (ChildControlsCreated == false && !creatingControls) {\r
-                               creatingControls = true;\r
-                                CreateChildControls();\r
-                                ChildControlsCreated = true;\r
-                               creatingControls = false;\r
-                        }\r
+                protected virtual void EnsureChildControls ()
+                {
+                        if (ChildControlsCreated == false && (stateMask & CREATING_CONTROLS) == 0) {
+                               stateMask |= CREATING_CONTROLS;
+                                CreateChildControls();
+                                ChildControlsCreated = true;
+                               stateMask &= ~CREATING_CONTROLS;
+                        }
                 }
 
                protected bool IsLiteralContent()
@@ -520,7 +520,7 @@ namespace System.Web.UI
                                if (String.Compare (id, c._userId, true) == 0)\r
                                        return c;\r
 \r
-                               if (!c._isNamingContainer && c.HasControls ()) {\r
+                               if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ()) {\r
                                        Control child = c.LookForControlByName (id);\r
                                        if (child != null)\r
                                                return child;\r
@@ -534,7 +534,7 @@ namespace System.Web.UI
                 {\r
                        EnsureChildControls ();\r
                        Control namingContainer = null;\r
-                       if (!_isNamingContainer) {\r
+                       if ((stateMask & IS_NAMING_CONTAINER) == 0) {
                                namingContainer = NamingContainer;\r
                                if (namingContainer == null)\r
                                        return null;\r
@@ -563,8 +563,8 @@ namespace System.Web.UI
                                ViewState.LoadViewState (savedState);
                                object o = ViewState ["Visible"];
                                if (o != null) {
-                                       _visible = (bool) o;
-                                       visibleChanged = true;
+                                       SetMask (VISIBLE, (bool) o);
+                                       stateMask |= VISIBLE_CHANGED;
                                }
                        }
                 }
@@ -651,7 +651,7 @@ namespace System.Web.UI
 
                 protected virtual object SaveViewState ()
                 {
-                       if (visibleChanged) {
+                       if ((stateMask & VISIBLE_CHANGED) != 0) {
                                ViewState ["Visible"] = Visible;
                        } else if (_viewState == null) {
                                return null;
@@ -664,7 +664,8 @@ namespace System.Web.UI
                 {\r
                        if (_viewState != null)\r
                                _viewState.TrackViewState ();\r
-                        _trackViewState = true;\r
+
+                        stateMask |= TRACK_VIEWSTATE;
                 }\r
                 \r
                 public virtual void Dispose()\r
@@ -761,7 +762,7 @@ namespace System.Web.UI
                        #if NET_2_0
                        bool foundDataItem = false;
                        
-                       if (_isNamingContainer && Page != null) {
+                       if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
                                object o = DataBinder.GetDataItem (this, out foundDataItem);
                                if (foundDataItem)
                                        Page.PushDataItemContext (o);
@@ -805,7 +806,7 @@ namespace System.Web.UI
 
                 public void RenderControl(HtmlTextWriter writer)
                 {
-                        if (_visible)
+                        if ((stateMask & VISIBLE) != 0)
                                 Render(writer);
                 }
 
@@ -848,7 +849,7 @@ namespace System.Web.UI
                                        c.LoadRecursive ();\r
                                }\r
                        }\r
-                       loaded = true;\r
+                       stateMask |= LOADED;
                 }\r
 \r
                 internal void UnloadRecursive(Boolean dispose)\r
@@ -869,7 +870,7 @@ namespace System.Web.UI
 
                 internal void PreRenderRecursiveInternal()
                 {
-                       if (_visible) {
+                       if ((stateMask & VISIBLE) != 0) {
                                EnsureChildControls ();
                                OnPreRender (EventArgs.Empty);
                                if (!HasControls ())
@@ -882,18 +883,18 @@ namespace System.Web.UI
                                        c.PreRenderRecursiveInternal ();
                                }
                        }
-                       prerendered = true;
+                       stateMask |= PRERENDERED;
                 }
 
                 internal void InitRecursive(Control namingContainer)\r
                 {\r
                         if (HasControls ()) {\r
-                               if (_isNamingContainer)\r
+                               if ((stateMask & IS_NAMING_CONTAINER) != 0)
                                        namingContainer = this;\r
 \r
                                if (namingContainer != null && \r
                                    namingContainer._userId == null &&\r
-                                   namingContainer.autoID)\r
+                                   namingContainer.AutoID)\r
                                        namingContainer._userId = namingContainer.GetDefaultName () + "b";\r
 \r
                                int len = Controls.Count;
@@ -902,17 +903,17 @@ namespace System.Web.UI
                                        Control c = Controls[i];\r
                                        c._page = Page;\r
                                        c._namingContainer = namingContainer;\r
-                                       if (namingContainer != null && c._userId == null && c.autoID)\r
+                                       if (namingContainer != null && c._userId == null && c.AutoID)\r
                                                c._userId = namingContainer.GetDefaultName () + "c";\r
                                        c.InitRecursive (namingContainer);      \r
                                }
                        }\r
 \r
-                       initing = true;
+                       stateMask |= INITING;
                         OnInit (EventArgs.Empty);\r
                        TrackViewState ();\r
-                       inited = true;\r
-                       initing = false;
+                       stateMask |= INITED;
+                       stateMask &= ~INITING;
                 }\r
 
                 internal object SaveViewStateRecursive ()
@@ -979,7 +980,7 @@ namespace System.Web.UI
                                }
                        }
 
-                       viewStateLoaded = true;
+                       stateMask |= VIEWSTATE_LOADED;
                 }
                 
                 void IParserAccessor.AddParsedSubObject(object obj)\r
@@ -1004,18 +1005,18 @@ namespace System.Web.UI
                                return (dataBindings!=null && dataBindings.Count>0);\r
                        }\r
                 }\r
-                \r
-               internal bool AutoID\r
-               {\r
-                       get { return autoID; }\r
-                       set { \r
-                               if (value == false && _isNamingContainer)\r
-                                       return;\r
-\r
-                               autoID = value;\r
-                       }\r
-               }\r
-\r
+               internal bool AutoID
+               {
+                       get { return (stateMask & AUTOID) != 0; }
+                       set {
+                               if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
+                                       return;
+
+                               SetMask (AUTOID, value);
+                       }
+               }
+
                 internal void PreventAutoID()\r
                 {\r
                        AutoID = false;\r
index 956030335e93288a0962c9adc0034fbb6b62cf62..6660aa750e630028dc20ab5c7385f922cd27486b 100755 (executable)
@@ -1,9 +1,11 @@
 //
 // System.Web.UI.ControlCollection.cs
 //
-// Duncan Mak  (duncan@ximian.com)
+// Authors:
+//     Duncan Mak  (duncan@ximian.com)
+//     Gonzalo Paniagua Javier (gonzalo@novell.com)
 //
-// (C) Ximian, Inc.
+// Copyright (c) 2002-2004 Novell, Inc. (http://www.novell.com)
 //
 
 //
@@ -34,41 +36,39 @@ namespace System.Web.UI {
 
        public class ControlCollection : ICollection, IEnumerable
        {
-               ArrayList list;
                Control owner;
+               Control [] controls;
+               int version;
+               int count;
+               bool readOnly;
                
                public ControlCollection (Control owner)
                {
                        if (owner == null)
-                               throw new ArgumentException ();
+                               throw new ArgumentException ("owner");
 
-                       list = new ArrayList ();
-                       this.owner = owner;
-               }
-
-               internal ControlCollection (Control owner, bool shortList)
-               {
-                       if (owner == null)
-                               throw new ArgumentException ();
-
-                       list = new ArrayList (shortList ? 1 : 0);
                        this.owner = owner;
                }
 
                public int Count {
-                       get { return list.Count; }
+                       get { return count; }
                }
 
                public bool IsReadOnly {
-                       get { return list.IsReadOnly; }
+                       get { return readOnly; }
                }
 
                public bool  IsSynchronized {
-                       get { return list.IsSynchronized; }
+                       get { return false; }
                }
 
                public virtual Control this [int index] {
-                       get { return list [index] as Control; }
+                       get {
+                               if (index < 0 || index >= count)
+                                       throw new ArgumentOutOfRangeException ("index");
+
+                               return controls [index];
+                       }
                }
 
                protected Control Owner {
@@ -76,18 +76,33 @@ namespace System.Web.UI {
                }
 
                public object SyncRoot {
-                       get { return list.SyncRoot; }
+                       get { return this; }
+               }
+
+               void EnsureControls ()
+               {
+                       if (controls == null) {
+                               controls = new Control [5];
+                       } else if (controls.Length < count + 1) {
+                               int n = controls.Length == 5 ? 3 : 2;
+                               Control [] newControls = new Control [controls.Length * n];
+                               Array.Copy (controls, 0, newControls, 0, controls.Length);
+                               controls = newControls;
+                       }
                }
 
                public virtual void Add (Control child)
                {
                        if (child == null)
                                throw new ArgumentNullException ();
-                       if (IsReadOnly)
+
+                       if (readOnly)
                                throw new HttpException ();
 
-                       list.Add (child);
-                       owner.AddedControl (child, list.Count - 1);
+                       EnsureControls ();
+                       version++;
+                       controls [count++] = child;
+                       owner.AddedControl (child, count - 1);
                }
 
                public virtual void AddAt (int index, Control child)
@@ -95,64 +110,131 @@ namespace System.Web.UI {
                        if (child == null) // maybe we should check for ! (child is Control)?
                                throw new ArgumentNullException ();
                        
-                       if ((index < -1) || (index > Count))
+                       if (index < -1 || index > count)
                                throw new ArgumentOutOfRangeException ();
 
-                       if (IsReadOnly)
+                       if (readOnly)
                                throw new HttpException ();
 
-                       if (index == -1){
+                       if (index == -1) {
                                Add (child);
-                       } else {
-                               list.Insert (index, child);
-                               owner.AddedControl (child, index);
+                               return;
                        }
+
+                       EnsureControls ();
+                       version++;
+                       Array.Copy (controls, index, controls, index + 1, count - index);
+                       count++;
+                       controls [index] = child;
+                       owner.AddedControl (child, index);
                }
 
                public virtual void Clear ()
                {
-                       foreach (Control ctrl in list) 
-                               owner.RemovedControl (ctrl);
+                       if (controls == null)
+                               return;
+
+                       version++;
+                       for (int i = 0; i < count; i++)
+                               owner.RemovedControl (controls [i]);
 
-                       list.Clear ();
+                       count = 0;
                        if (owner != null)
                                owner.ResetChildNames ();
                }
 
                public virtual bool Contains (Control c)
                {
-                       return list.Contains (c);
+                       return (controls != null && Array.IndexOf (controls, c) != -1);
                }
 
                public void CopyTo (Array array, int index)
                {
-                       list.CopyTo (array, index);
+                       if (controls == null)
+                               return;
+
+                       controls.CopyTo (array, index);
                }
 
                public IEnumerator GetEnumerator ()
                {
-                       return list.GetEnumerator ();
+                       return new SimpleEnumerator (this);
                }
 
                public virtual int IndexOf (Control c)
                {
-                       return list.IndexOf (c);
+                       if (controls == null)
+                               return -1;
+
+                       return Array.IndexOf (controls, c);
                }
 
                public virtual void Remove (Control value)
                {
-                       list.Remove (value);
-                       owner.RemovedControl (value);
+                       int idx = IndexOf (value);
+                       if (idx == -1)
+                               return;
+                       RemoveAt (idx);
                }
 
                public virtual void RemoveAt (int index)
                {
-                       if (IsReadOnly)
+                       if (readOnly)
                                throw new HttpException ();
 
-                       Control value = (Control) list [index];
-                       list.RemoveAt (index);
-                       owner.RemovedControl (value);
+                       version++;
+                       Control ctrl = controls [index];
+                       Array.Copy (controls, index + 1, controls, index, count - index);
+                       count--;
+                       owner.RemovedControl (ctrl);
+               }
+
+               // Almost the same as in ArrayList
+               sealed class SimpleEnumerator : IEnumerator
+               {
+                       ControlCollection coll;
+                       int index;
+                       int version;
+                       object currentElement;
+                                                       
+                       public SimpleEnumerator (ControlCollection coll)
+                       {
+                               this.coll = coll;
+                               index = -1;
+                               version = coll.version;
+                       }
+       
+                       public bool MoveNext ()
+                       {
+                               if (version != coll.version)
+                                       throw new InvalidOperationException ("List has changed.");
+                               
+                               if (index >= -1 && ++index < coll.Count) {
+                                       currentElement = coll [index];
+                                       return true;
+                               } else {
+                                       index = -2;
+                                       return false;
+                               }
+                       }
+       
+                       public object Current {
+                               get {
+                                       if (index < 0)
+                                               throw new InvalidOperationException (index == -1 ? "Enumerator not started" : "Enumerator ended");
+                                       
+                                       return currentElement;
+                               }
+                       }
+       
+                       public void Reset ()
+                       {
+                               if (version != coll.version)
+                                       throw new InvalidOperationException ("List has changed.");
+                               
+                               index = -1;
+                       }
                }
        }
 }
+
index 90592e9d039fa57f7f142f7d3f90d0db4df28d65..2ead5502da017e38e27c6879425f5cda2acd6786 100755 (executable)
@@ -34,7 +34,7 @@ namespace System.Web.UI {
        public class EmptyControlCollection : ControlCollection
        {
                public EmptyControlCollection (Control owner)
-                       : base (owner, true)
+                       : base (owner)
                {
                }