[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];
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
#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
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
[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
}
}\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
#endif
public virtual bool Visible {
get {
- if (_visible == false)
+ if ((stateMask & VISIBLE) == 0)
return false;
if (_parent != null)
}
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)]
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)]
}\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
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;
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) {
}
}
- if (loaded)
+ if ((stateMask & LOADED) != 0)
control.LoadRecursive ();
- if (prerendered)
+ if ((stateMask & PRERENDERED) != 0)
control.PreRenderRecursiveInternal ();
}
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()
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
{\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
ViewState.LoadViewState (savedState);
object o = ViewState ["Visible"];
if (o != null) {
- _visible = (bool) o;
- visibleChanged = true;
+ SetMask (VISIBLE, (bool) o);
+ stateMask |= VISIBLE_CHANGED;
}
}
}
protected virtual object SaveViewState ()
{
- if (visibleChanged) {
+ if ((stateMask & VISIBLE_CHANGED) != 0) {
ViewState ["Visible"] = Visible;
} else if (_viewState == null) {
return null;
{\r
if (_viewState != null)\r
_viewState.TrackViewState ();\r
- _trackViewState = true;\r
+
+ stateMask |= TRACK_VIEWSTATE;
}\r
\r
public virtual void Dispose()\r
#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);
public void RenderControl(HtmlTextWriter writer)
{
- if (_visible)
+ if ((stateMask & VISIBLE) != 0)
Render(writer);
}
c.LoadRecursive ();\r
}\r
}\r
- loaded = true;\r
+ stateMask |= LOADED;
}\r
\r
internal void UnloadRecursive(Boolean dispose)\r
internal void PreRenderRecursiveInternal()
{
- if (_visible) {
+ if ((stateMask & VISIBLE) != 0) {
EnsureChildControls ();
OnPreRender (EventArgs.Empty);
if (!HasControls ())
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;
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 ()
}
}
- viewStateLoaded = true;
+ stateMask |= VIEWSTATE_LOADED;
}
void IParserAccessor.AddParsedSubObject(object obj)\r
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
//
// 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)
//
//
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 {
}
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)
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;
+ }
}
}
}
+