2 // System.Web.UI.Control.cs
5 // Bob Smith <bob@thestuff.net>
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com
7 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 // Sanjay Gupta (gsanjay@novell.com)
11 // (c) 2002,2003 Ximian, Inc. (http://www.ximian.com)
12 // (C) 2004 Novell, Inc. (http://www.novell.com)
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 // This will provide extra information when trace is enabled. Might be too verbose.
39 using System.Collections;
40 using System.ComponentModel;
41 using System.ComponentModel.Design;
42 using System.ComponentModel.Design.Serialization;
43 using System.Security.Permissions;
45 using System.Web.Util;
46 using System.Globalization;
48 using System.Web.UI.Adapters;
52 namespace System.Web.UI
55 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
56 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
58 [DefaultProperty ("ID"), DesignerCategory ("Code"), ToolboxItemFilter ("System.Web.UI", ToolboxItemFilterType.Require)]
59 [ToolboxItem ("System.Web.UI.Design.WebControlToolboxItem, " + Consts.AssemblySystem_Design)]
60 [Designer ("System.Web.UI.Design.ControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
62 [DesignerSerializer ("Microsoft.VisualStudio.Web.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VisualStudio_Web,
63 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
67 [DesignerSerializer ("Microsoft.VSDesigner.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VSDesigner,
68 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
70 public partial class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor
72 , IUrlResolutionService, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor
75 static readonly object DataBindingEvent = new object();
76 static readonly object DisposedEvent = new object();
77 static readonly object InitEvent = new object();
78 static readonly object LoadEvent = new object();
79 static readonly object PreRenderEvent = new object();
80 static readonly object UnloadEvent = new object();
81 static string[] defaultNameArray;
84 const int databinding_mask = 1;
85 const int disposed_mask = 1 << 1;
86 const int init_mask = 1 << 2;
87 const int load_mask = 1 << 3;
88 const int prerender_mask = 1 << 4;
89 const int unload_mask = 1 << 5;
94 ControlCollection _controls;
95 Control _namingContainer;
101 EventHandlerList _events;
102 RenderMethod _renderMethodDelegate;
105 DataBindingCollection dataBindings;
106 Hashtable pendingVS; // may hold unused viewstate data from child controls
110 TemplateControl _templateControl;
111 bool _isChildControlStateCleared;
112 string _templateSourceDirectory;
116 const int ENABLE_VIEWSTATE = 1;
117 const int VISIBLE = 1 << 1;
118 const int AUTOID = 1 << 2;
119 const int CREATING_CONTROLS = 1 << 3;
120 const int BINDING_CONTAINER = 1 << 4;
121 const int AUTO_EVENT_WIREUP = 1 << 5;
122 const int IS_NAMING_CONTAINER = 1 << 6;
123 const int VISIBLE_CHANGED = 1 << 7;
124 const int TRACK_VIEWSTATE = 1 << 8;
125 const int CHILD_CONTROLS_CREATED = 1 << 9;
126 const int ID_SET = 1 << 10;
127 const int INITED = 1 << 11;
128 const int INITING = 1 << 12;
129 const int VIEWSTATE_LOADED = 1 << 13;
130 const int LOADED = 1 << 14;
131 const int PRERENDERED = 1 << 15;
133 const int ENABLE_THEMING = 1 << 16;
139 defaultNameArray = new string [100];
140 for (int i = 0 ; i < 100 ; i++)
142 defaultNameArray [i] = String.Format("ctl{0:D2}", i);
144 defaultNameArray [i] = "_ctl" + i;
150 stateMask = ENABLE_VIEWSTATE | VISIBLE | AUTOID | BINDING_CONTAINER | AUTO_EVENT_WIREUP;
151 if (this is INamingContainer)
152 stateMask |= IS_NAMING_CONTAINER;
156 [MonoTODO("Not implemented, always returns null")]
157 protected ControlAdapter Adapter
160 // for the time being, fool the
161 // Control machinery into thinking we
162 // don't have an Adapter. This will
163 // allow us to write all the rest of
164 // the Adapter handling code without
165 // having to worry about *having*
171 string _appRelativeTemplateSourceDirectory = null;
173 [EditorBrowsable (EditorBrowsableState.Advanced)]
175 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
176 public string AppRelativeTemplateSourceDirectory
179 if (_appRelativeTemplateSourceDirectory != null && !(this is MasterPage))
180 return _appRelativeTemplateSourceDirectory;
183 return Parent.AppRelativeTemplateSourceDirectory;
187 [EditorBrowsable (EditorBrowsableState.Never)]
188 set { _appRelativeTemplateSourceDirectory = value; }
193 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
194 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
195 public Control BindingContainer {
197 Control container = NamingContainer;
198 if (container != null && (container.stateMask & BINDING_CONTAINER) == 0)
199 container = container.BindingContainer;
204 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
206 [WebSysDescription ("An Identification of the control that is rendered.")]
207 public virtual string ClientID {
209 string client = UniqueID;
213 client = UniqueID2ClientID (client);
215 client = client.Replace (':', ClientIDSeparator);
224 internal string UniqueID2ClientID (string uniqueId)
226 return uniqueId.Replace (IdSeparator, ClientIDSeparator);
229 protected char ClientIDSeparator
231 char ClientIDSeparator
240 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
242 [WebSysDescription ("The child controls of this control.")]
243 public virtual ControlCollection Controls //DIT
247 if (_controls == null) _controls = CreateControlCollection();
253 [MonoTODO ("revisit once we have a real design strategy")]
254 protected internal bool DesignMode
256 get { return false; }
260 [DefaultValue (true), WebCategory ("Behavior")]
261 [WebSysDescription ("An Identification of the control that is rendered.")]
265 public virtual bool EnableViewState {
266 get { return ((stateMask & ENABLE_VIEWSTATE) != 0); }
267 set { SetMask (ENABLE_VIEWSTATE, value); }
270 [MergableProperty (false), ParenthesizePropertyName (true)]
271 [WebSysDescription ("The name of the control that is rendered.")]
273 [Filterable (false), Themeable (false)]
276 public virtual string ID {
278 return (((stateMask & ID_SET) != 0) ? _userId : null);
292 protected char IdSeparator
299 protected internal bool IsChildControlStateCleared {
300 get { return _isChildControlStateCleared; }
303 protected internal bool IsViewStateEnabled
307 for (Control control = this; control != null; control = control.Parent)
308 if (!control.EnableViewState)
315 protected bool LoadViewStateByID
323 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
325 [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]
326 public virtual Control NamingContainer {
328 if (_namingContainer == null && _parent != null) {
329 if ((_parent.stateMask & IS_NAMING_CONTAINER) == 0)
330 _namingContainer = _parent.NamingContainer;
332 _namingContainer = _parent;
335 return _namingContainer;
339 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
341 [WebSysDescription ("The webpage that this control resides on.")]
345 public virtual Page Page //DIT
349 if (_page == null && _parent != null) _page = _parent.Page;
358 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
360 [WebSysDescription ("The parent control of this control.")]
361 public virtual Control Parent //DIT
369 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
370 [EditorBrowsable (EditorBrowsableState.Advanced), Browsable (false)]
371 [WebSysDescription ("The site this control is part of.")]
372 public ISite Site //DIT
386 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
387 public TemplateControl TemplateControl {
389 if (_templateControl != null)
390 return _templateControl;
392 return _parent.TemplateControl;
396 [EditorBrowsable (EditorBrowsableState.Never)]
397 set { _templateControl = value; }
402 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
404 [WebSysDescription ("A virtual directory containing the parent of the control.")]
405 public virtual string TemplateSourceDirectory {
408 if (_templateSourceDirectory == null) {
409 TemplateControl tc = TemplateControl;
412 HttpContext ctx = Context;
414 _templateSourceDirectory = VirtualPathUtility.GetDirectory (ctx.Request.CurrentExecutionFilePath);
415 } else if (tc != this)
416 _templateSourceDirectory = tc.TemplateSourceDirectory;
418 if (_templateSourceDirectory == null && this is TemplateControl) {
419 string path = ((TemplateControl)this).AppRelativeVirtualPath;
422 // Pretend our application virtual root is "/" even if it isn't - we just
423 // want to get an absolute url out of relative one, without the real
424 // application root prepended to it.
425 string ret = VirtualPathUtility.GetDirectory (VirtualPathUtility.ToAbsolute (path, "/"));
426 int len = ret.Length;
429 if (ret [--len] == '/')
430 _templateSourceDirectory = ret.Substring (0, len);
432 _templateSourceDirectory = String.Empty;
434 if (_templateSourceDirectory == null)
435 _templateSourceDirectory = String.Empty;
438 return _templateSourceDirectory;
440 return (_parent == null) ? String.Empty : _parent.TemplateSourceDirectory;
446 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
448 [WebSysDescription ("The unique ID of the control.")]
449 public virtual string UniqueID {
451 if (uniqueID != null)
454 if (_namingContainer == null) {
455 if ((stateMask & IS_NAMING_CONTAINER) == 0)
456 _namingContainer = NamingContainer;
457 if (_namingContainer == null)
462 _userId = _namingContainer.GetDefaultName ();
464 string prefix = _namingContainer.UniqueID;
466 // For J2EE portlets we need to add the namespace to the ID.
467 if (_namingContainer == _page && _page.PortletNamespace != null)
468 prefix = _page.PortletNamespace;
471 if (_namingContainer == _page || prefix == null) {
477 uniqueID = prefix + IdSeparator + _userId;
479 uniqueID = prefix + ":" + _userId;
485 void SetMask (int m, bool val)
493 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
494 [WebSysDescription ("Visiblity state of the control.")]
495 public virtual bool Visible {
497 if ((stateMask & VISIBLE) == 0)
501 return _parent.Visible;
507 if ((value && (stateMask & VISIBLE) == 0) ||
508 (!value && (stateMask & VISIBLE) != 0)) {
509 if (IsTrackingViewState)
510 stateMask |= VISIBLE_CHANGED;
513 SetMask (VISIBLE, value);
517 protected bool ChildControlsCreated {
518 get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
520 if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
521 if (_controls != null)
525 SetMask (CHILD_CONTROLS_CREATED, value);
530 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
531 protected virtual HttpContext Context //DIT
536 if (_context != null)
539 return HttpContext.Current;
540 context = _parent.Context;
543 return HttpContext.Current;
547 protected EventHandlerList Events {
550 _events = new EventHandlerList ();
555 protected bool HasChildViewState {
557 return (pendingVS != null && pendingVS.Count > 0);
561 protected bool IsTrackingViewState {
562 get { return ((stateMask & TRACK_VIEWSTATE) != 0); }
566 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
567 [WebSysDescription ("ViewState")]
568 protected virtual StateBag ViewState
572 if(_viewState == null)
573 _viewState = new StateBag (ViewStateIgnoresCase);
575 if (IsTrackingViewState)
576 _viewState.TrackViewState ();
583 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
584 protected virtual bool ViewStateIgnoresCase
591 internal bool AutoEventWireup {
592 get { return (stateMask & AUTO_EVENT_WIREUP) != 0; }
593 set { SetMask (AUTO_EVENT_WIREUP, value); }
596 internal void SetBindingContainer (bool isBC)
598 SetMask (BINDING_CONTAINER, isBC);
601 internal void ResetChildNames ()
606 string GetDefaultName ()
609 if (defaultNumberID > 99) {
611 defaultName = "ctl" + defaultNumberID++;
613 defaultName = "_ctl" + defaultNumberID++;
616 defaultName = defaultNameArray [defaultNumberID++];
621 void NullifyUniqueID ()
627 foreach (Control c in _controls)
628 c.NullifyUniqueID ();
631 protected internal virtual void AddedControl (Control control, int index)
633 /* Ensure the control don't have more than 1 parent */
634 if (control._parent != null)
635 control._parent.Controls.Remove (control);
637 control._parent = this;
638 control._page = _page;
639 Control nc = ((stateMask & IS_NAMING_CONTAINER) != 0) ? this : NamingContainer;
642 control._namingContainer = nc;
643 if (control.AutoID == true && control._userId == null)
644 control._userId = nc.GetDefaultName ();
647 if ((stateMask & (INITING | INITED)) != 0)
648 control.InitRecursive (nc);
650 if ((stateMask & (VIEWSTATE_LOADED | LOADED)) != 0) {
651 if (pendingVS != null) {
652 object vs = pendingVS [index];
654 pendingVS.Remove (index);
655 if (pendingVS.Count == 0)
658 control.LoadViewStateRecursive (vs);
663 if ((stateMask & LOADED) != 0)
664 control.LoadRecursive ();
666 if ((stateMask & PRERENDERED) != 0)
667 control.PreRenderRecursiveInternal ();
670 protected virtual void AddParsedSubObject(object obj) //DIT
672 Control c = obj as Control;
673 if (c != null) Controls.Add(c);
677 [EditorBrowsable (EditorBrowsableState.Advanced)]
678 public virtual void ApplyStyleSheetSkin (Page page)
680 if (!EnableTheming) /* this enough? */
683 /* apply the style sheet skin here */
684 if (page.StyleSheetPageTheme != null) {
685 ControlSkin cs = page.StyleSheetPageTheme.GetControlSkin (GetType(), SkinID);
692 protected void BuildProfileTree(string parentId, bool calcViewState)
698 protected void ClearChildControlState ()
700 _isChildControlStateCleared = true;
703 protected void ClearChildState ()
705 ClearChildViewState ();
706 ClearChildControlState ();
710 protected void ClearChildViewState ()
720 virtual void CreateChildControls() {} //DIT
722 protected virtual ControlCollection CreateControlCollection() //DIT
724 return new ControlCollection(this);
727 protected virtual void EnsureChildControls ()
729 if (ChildControlsCreated == false && (stateMask & CREATING_CONTROLS) == 0) {
730 stateMask |= CREATING_CONTROLS;
733 Adapter.CreateChildControls ();
736 CreateChildControls();
737 ChildControlsCreated = true;
738 stateMask &= ~CREATING_CONTROLS;
743 protected void EnsureID ()
747 ID = NamingContainer.GetDefaultName ();
750 protected bool HasEvents ()
752 return _events != null;
758 protected bool IsLiteralContent()
760 if (HasControls () && _controls.Count == 1 && (_controls [0] is LiteralControl))
766 [WebSysDescription ("")]
767 public virtual Control FindControl (string id)
769 return FindControl (id, 0);
772 Control LookForControlByName (string id)
775 if (this == Page && id != null && id == Page.PortletNamespace)
781 Control result = null;
782 foreach (Control c in _controls) {
783 if (String.Compare (id, c._userId, true, CultureInfo.InvariantCulture) == 0) {
784 if (result != null && result != c) {
785 throw new HttpException ("1 Found more than one control with ID '" + id + "'");
792 if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ()) {
793 Control child = c.LookForControlByName (id);
795 if (result != null && result != child)
796 throw new HttpException ("2 Found more than one control with ID '" + id + "'");
806 protected virtual Control FindControl (string id, int pathOffset)
808 EnsureChildControls ();
809 Control namingContainer = null;
810 if ((stateMask & IS_NAMING_CONTAINER) == 0) {
811 namingContainer = NamingContainer;
812 if (namingContainer == null)
815 return namingContainer.FindControl (id, pathOffset);
821 int separatorIdx = id.IndexOf (IdSeparator, pathOffset);
823 int separatorIdx = id.IndexOf (':', pathOffset);
825 if (separatorIdx == -1)
826 return LookForControlByName (id.Substring (pathOffset));
828 string idfound = id.Substring (pathOffset, separatorIdx - pathOffset);
829 namingContainer = LookForControlByName (idfound);
830 if (namingContainer == null)
833 return namingContainer.FindControl (id, separatorIdx + 1);
836 protected virtual void LoadViewState(object savedState)
838 if (savedState != null) {
839 ViewState.LoadViewState (savedState);
840 object o = ViewState ["Visible"];
842 SetMask (VISIBLE, (bool) o);
843 stateMask |= VISIBLE_CHANGED;
848 // [MonoTODO("Secure?")]
849 protected string MapPathSecure(string virtualPath)
851 string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
852 return Context.Request.MapPath (combined);
855 protected virtual bool OnBubbleEvent(object source, EventArgs args) //DIT
858 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
859 string type_name = null;
861 type_name = GetType ().Name;
862 trace.Write ("control", String.Format ("OnBubbleEvent {0} {1}", _userId, type_name));
868 protected virtual void OnDataBinding (EventArgs e)
870 if ((event_mask & databinding_mask) != 0) {
871 EventHandler eh = (EventHandler)(_events [DataBindingEvent]);
874 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
875 string type_name = null;
877 type_name = GetType ().Name;
878 trace.Write ("control", String.Format ("OnDataBinding {0} {1}", _userId, type_name));
891 virtual void OnInit (EventArgs e)
893 if ((event_mask & init_mask) != 0) {
894 EventHandler eh = (EventHandler)(_events [InitEvent]);
897 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
898 string type_name = null;
900 type_name = GetType ().Name;
901 trace.Write ("control", String.Format ("OnInit {0} {1}", _userId, type_name));
914 virtual void OnLoad (EventArgs e)
916 if ((event_mask & load_mask) != 0) {
917 EventHandler eh = (EventHandler)(_events [LoadEvent]);
920 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
921 string type_name = null;
923 type_name = GetType ().Name;
924 trace.Write ("control", String.Format ("OnLoad {0} {1}", _userId, type_name));
937 virtual void OnPreRender (EventArgs e)
939 if ((event_mask & prerender_mask) != 0) {
940 EventHandler eh = (EventHandler)(_events [PreRenderEvent]);
943 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
944 string type_name = null;
946 type_name = GetType ().Name;
947 trace.Write ("control", String.Format ("OnPreRender {0} {1}", _userId, type_name));
960 virtual void OnUnload(EventArgs e)
962 if ((event_mask & unload_mask) != 0) {
963 EventHandler eh = (EventHandler)(_events [UnloadEvent]);
966 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
967 string type_name = null;
969 type_name = GetType ().Name;
970 trace.Write ("control", String.Format ("OnUnload {0} {1}", _userId, type_name));
979 protected internal Stream OpenFile (string path)
982 string filePath = Context.Server.MapPath (path);
983 return File.OpenRead (filePath);
985 catch (UnauthorizedAccessException) {
986 throw new HttpException ("Access to the specified file was denied.");
990 internal string GetPhysicalFilePath (string virtualPath)
994 if (VirtualPathUtility.IsAbsolute (virtualPath))
995 return page != null ? page.MapPath (virtualPath) : Context.Server.MapPath (virtualPath);
997 // We need to determine whether one of our parents is a
998 // master page. If so, we need to map the path
999 // relatively to the master page and not our containing
1000 // page/control. This is necessary for cases when a
1001 // relative path is used in a control placed in a master
1002 // page and the master page is referenced from a
1003 // location other than its own. In such cases MS.NET looks
1004 // for the file in the directory where the master page
1007 // An example of where it is needed is at
1009 // http://quickstarts.asp.net/QuickStartv20/aspnet/samples/masterpages/masterpages_cs/pages/default.aspx
1011 MasterPage master = null;
1012 Control ctrl = Parent;
1014 while (ctrl != null) {
1015 if (ctrl is MasterPage) {
1016 master = ctrl as MasterPage;
1024 path = VirtualPathUtility.Combine (master.TemplateSourceDirectory, virtualPath);
1026 path = VirtualPathUtility.Combine (TemplateSourceDirectory, virtualPath);
1027 return page != null ? page.MapPath (path) : Context.Server.MapPath (path);
1031 protected void RaiseBubbleEvent(object source, EventArgs args)
1036 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1037 string type_name = null;
1038 if (trace != null) {
1039 type_name = GetType ().Name;
1040 trace.Write ("control", String.Format ("RaiseBubbleEvent {0} {1}", _userId, type_name));
1043 if (c.OnBubbleEvent (source, args)) {
1046 trace.Write ("control", String.Format ("End RaiseBubbleEvent (false) {0} {1}", _userId, type_name));
1052 trace.Write ("control", String.Format ("End RaiseBubbleEvent (true) {0} {1}", _userId, type_name));
1063 virtual void Render(HtmlTextWriter writer) //DIT
1065 RenderChildren(writer);
1073 virtual void RenderChildren (HtmlTextWriter writer) //DIT
1075 if (_renderMethodDelegate != null) {
1076 _renderMethodDelegate (writer, this);
1077 } else if (_controls != null) {
1078 int len = _controls.Count;
1079 for (int i = 0; i < len; i++) {
1080 Control c = _controls [i];
1082 if (c.Adapter != null)
1083 c.RenderControl (writer, c.Adapter);
1086 c.RenderControl (writer);
1092 protected virtual ControlAdapter ResolveAdapter ()
1094 throw new NotImplementedException ();
1098 protected virtual object SaveViewState ()
1100 if ((stateMask & VISIBLE_CHANGED) != 0) {
1101 ViewState ["Visible"] = (stateMask & VISIBLE) != 0;
1102 } else if (_viewState == null) {
1106 return _viewState.SaveViewState ();
1109 protected virtual void TrackViewState()
1111 if (_viewState != null)
1112 _viewState.TrackViewState ();
1114 stateMask |= TRACK_VIEWSTATE;
1117 public virtual void Dispose ()
1119 if ((event_mask & disposed_mask) != 0) {
1120 EventHandler eh = (EventHandler)(_events [DisposedEvent]);
1121 if (eh != null) eh (this, EventArgs.Empty);
1125 [WebCategory ("FIXME")]
1126 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]
1127 public event EventHandler DataBinding {
1129 event_mask |= databinding_mask;
1130 Events.AddHandler (DataBindingEvent, value);
1132 remove { Events.RemoveHandler (DataBindingEvent, value); }
1135 [WebSysDescription ("Raised when the contol is disposed.")]
1136 public event EventHandler Disposed {
1138 event_mask |= disposed_mask;
1139 Events.AddHandler (DisposedEvent, value);
1141 remove { Events.RemoveHandler (DisposedEvent, value); }
1144 [WebSysDescription ("Raised when the page containing the control is initialized.")]
1145 public event EventHandler Init {
1147 event_mask |= init_mask;
1148 Events.AddHandler (InitEvent, value);
1150 remove { Events.RemoveHandler (InitEvent, value); }
1153 [WebSysDescription ("Raised after the page containing the control has been loaded.")]
1154 public event EventHandler Load {
1156 event_mask |= load_mask;
1157 Events.AddHandler (LoadEvent, value);
1159 remove { Events.RemoveHandler (LoadEvent, value); }
1162 [WebSysDescription ("Raised before the page containing the control is rendered.")]
1163 public event EventHandler PreRender {
1165 event_mask |= prerender_mask;
1166 Events.AddHandler (PreRenderEvent, value);
1168 remove { Events.RemoveHandler (PreRenderEvent, value); }
1171 [WebSysDescription ("Raised when the page containing the control is unloaded.")]
1172 public event EventHandler Unload {
1174 event_mask |= unload_mask;
1175 Events.AddHandler (UnloadEvent, value);
1177 remove { Events.RemoveHandler (UnloadEvent, value); }
1180 public virtual void DataBind() //DIT
1185 OnDataBinding (EventArgs.Empty);
1194 void DataBindChildren ()
1196 if (!HasControls ())
1199 int len = _controls.Count;
1200 for (int i = 0; i < len; i++) {
1201 Control c = _controls [i];
1207 public virtual bool HasControls ()
1209 return (_controls != null && _controls.Count > 0);
1217 void RenderControl (HtmlTextWriter writer)
1219 if ((stateMask & VISIBLE) != 0) {
1220 HttpContext ctx = Context;
1221 TraceContext trace = (ctx != null) ? ctx.Trace : null;
1223 if ((trace != null) && trace.IsEnabled)
1224 pos = ctx.Response.GetOutputByteCount ();
1227 if ((trace != null) && trace.IsEnabled) {
1228 int size = ctx.Response.GetOutputByteCount () - pos;
1229 trace.SaveSize (this, size >= 0 ? size : 0);
1235 protected void RenderControl (HtmlTextWriter writer,
1236 ControlAdapter adapter)
1238 if ((stateMask & VISIBLE) != 0) {
1239 adapter.BeginRender (writer);
1240 adapter.Render (writer);
1241 adapter.EndRender (writer);
1246 public string ResolveUrl (string relativeUrl)
1248 if (relativeUrl == null)
1249 throw new ArgumentNullException ("relativeUrl");
1251 if (relativeUrl == "")
1254 if (relativeUrl [0] == '#')
1257 string ts = TemplateSourceDirectory;
1258 if (ts == null || ts.Length == 0 ||
1259 Context == null || Context.Response == null ||
1260 !UrlUtils.IsRelativeUrl (relativeUrl))
1263 HttpResponse resp = Context.Response;
1264 return resp.ApplyAppPathModifier (UrlUtils.Combine (ts, relativeUrl));
1273 string ResolveClientUrl (string relativeUrl)
1276 // There are no relative paths when rendering a J2EE portlet
1277 if (Page != null && Page.PortletNamespace != null)
1278 return ResolveUrl (relativeUrl);
1280 if (relativeUrl == null)
1281 throw new ArgumentNullException ("relativeUrl");
1283 if (relativeUrl.Length == 0)
1284 return String.Empty;
1286 if (VirtualPathUtility.IsAbsolute (relativeUrl) || relativeUrl.IndexOf (':') >= 0)
1289 HttpContext context = Context;
1290 if (context != null && context.Request != null) {
1291 string basePath = context.Request.CurrentExecutionFilePath;
1293 if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/')
1294 basePath = VirtualPathUtility.GetDirectory (basePath);
1296 if(VirtualPathUtility.IsAppRelative(relativeUrl))
1297 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1299 string templateSourceDirectory = TemplateSourceDirectory;
1300 if (templateSourceDirectory == null || templateSourceDirectory.Length == 0)
1303 string templatePath = VirtualPathUtility.AppendTrailingSlash (templateSourceDirectory);
1305 if (basePath.Length == templatePath.Length && String.CompareOrdinal (basePath, templatePath) == 0)
1308 relativeUrl = VirtualPathUtility.Combine (templatePath, relativeUrl);
1309 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1314 internal bool HasRenderMethodDelegate () {
1315 return _renderMethodDelegate != null;
1318 [EditorBrowsable (EditorBrowsableState.Advanced)]
1319 public void SetRenderMethodDelegate(RenderMethod renderMethod) //DIT
1321 _renderMethodDelegate = renderMethod;
1324 internal void LoadRecursive()
1327 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1328 string type_name = null;
1329 if (trace != null) {
1330 type_name = GetType ().Name;
1331 trace.Write ("control", String.Format ("LoadRecursive {0} {1}", _userId, type_name));
1335 if (Adapter != null)
1336 Adapter.OnLoad (EventArgs.Empty);
1339 OnLoad (EventArgs.Empty);
1340 if (HasControls ()) {
1341 int len = _controls.Count;
1342 for (int i=0;i<len;i++)
1344 Control c = _controls[i];
1351 trace.Write ("control", String.Format ("End LoadRecursive {0} {1}", _userId, type_name));
1353 stateMask |= LOADED;
1356 internal void UnloadRecursive(Boolean dispose)
1359 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1360 string type_name = null;
1361 if (trace != null) {
1362 type_name = GetType ().Name;
1363 trace.Write ("control", String.Format ("UnloadRecursive {0} {1}", _userId, type_name));
1366 if (HasControls ()) {
1367 int len = _controls.Count;
1368 for (int i=0;i<len;i++)
1370 Control c = _controls[i];
1371 c.UnloadRecursive (dispose);
1377 trace.Write ("control", String.Format ("End UnloadRecursive {0} {1}", _userId, type_name));
1380 if (Adapter != null)
1381 Adapter.OnUnload (EventArgs.Empty);
1384 OnUnload (EventArgs.Empty);
1389 internal void PreRenderRecursiveInternal()
1391 if ((stateMask & VISIBLE) != 0) {
1392 EnsureChildControls ();
1394 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1395 string type_name = null;
1396 if (trace != null) {
1397 type_name = GetType ().Name;
1398 trace.Write ("control", String.Format ("PreRenderRecursive {0} {1}", _userId, type_name));
1402 if (Adapter != null)
1403 Adapter.OnPreRender (EventArgs.Empty);
1406 OnPreRender (EventArgs.Empty);
1407 if (!HasControls ())
1410 int len = _controls.Count;
1411 for (int i=0;i<len;i++)
1413 Control c = _controls[i];
1414 c.PreRenderRecursiveInternal ();
1418 trace.Write ("control", String.Format ("End PreRenderRecursive {0} {1}", _userId, type_name));
1421 stateMask |= PRERENDERED;
1424 internal void InitRecursive(Control namingContainer)
1427 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1428 string type_name = null;
1429 if (trace != null) {
1430 type_name = GetType ().Name;
1431 trace.Write ("control", String.Format ("InitRecursive {0} {1}", _userId, type_name));
1434 if (HasControls ()) {
1435 if ((stateMask & IS_NAMING_CONTAINER) != 0)
1436 namingContainer = this;
1438 if (namingContainer != null &&
1439 namingContainer._userId == null &&
1440 namingContainer.AutoID)
1441 namingContainer._userId = namingContainer.GetDefaultName () + "b";
1443 int len = _controls.Count;
1444 for (int i=0;i<len;i++)
1446 Control c = _controls[i];
1448 c._namingContainer = namingContainer;
1449 if (namingContainer != null && c._userId == null && c.AutoID)
1450 c._userId = namingContainer.GetDefaultName () + "c";
1451 c.InitRecursive (namingContainer);
1455 stateMask |= INITING;
1459 if (Adapter != null)
1460 Adapter.OnInit (EventArgs.Empty);
1463 OnInit (EventArgs.Empty);
1466 trace.Write ("control", String.Format ("End InitRecursive {0} {1}", _userId, type_name));
1469 stateMask |= INITED;
1470 stateMask &= ~INITING;
1473 internal object SaveViewStateRecursive ()
1475 if (!EnableViewState)
1479 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1480 string type_name = null;
1481 if (trace != null) {
1482 type_name = GetType ().Name;
1483 trace.Write ("control", String.Format ("SaveViewStateRecursive {0} {1}", _userId, type_name));
1487 ArrayList controlList = null;
1488 ArrayList controlStates = null;
1493 int len = _controls.Count;
1494 for (int i=0;i<len;i++)
1496 Control ctrl = _controls[i];
1497 object ctrlState = ctrl.SaveViewStateRecursive ();
1499 if (ctrlState == null)
1502 if (controlList == null)
1504 controlList = new ArrayList ();
1505 controlStates = new ArrayList ();
1508 controlList.Add (idx);
1509 controlStates.Add (ctrlState);
1513 object thisState = SaveViewState ();
1514 if (thisState == null && controlList == null && controlStates == null) {
1516 if (trace != null) {
1517 trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved nothing", _userId, type_name));
1518 trace.SaveViewState (this, null);
1525 if (trace != null) {
1526 trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved a Triplet", _userId, type_name));
1527 trace.SaveViewState (this, thisState);
1530 return new Triplet (thisState, controlList, controlStates);
1533 internal void LoadViewStateRecursive (object savedState)
1535 if (!EnableViewState || savedState == null)
1539 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1540 string type_name = null;
1541 if (trace != null) {
1542 type_name = GetType ().Name;
1543 trace.Write ("control", String.Format ("LoadViewStateRecursive {0} {1}", _userId, type_name));
1546 Triplet savedInfo = (Triplet) savedState;
1547 LoadViewState (savedInfo.First);
1549 ArrayList controlList = savedInfo.Second as ArrayList;
1550 if (controlList == null)
1552 ArrayList controlStates = savedInfo.Third as ArrayList;
1553 int nControls = controlList.Count;
1554 for (int i = 0; i < nControls; i++) {
1555 int k = (int) controlList [i];
1556 if (k < Controls.Count && controlStates != null) {
1557 Control c = Controls [k];
1558 c.LoadViewStateRecursive (controlStates [i]);
1560 if (pendingVS == null)
1561 pendingVS = new Hashtable ();
1563 pendingVS [k] = controlStates [i];
1569 trace.Write ("control", String.Format ("End LoadViewStateRecursive {0} {1}", _userId, type_name));
1571 stateMask |= VIEWSTATE_LOADED;
1575 internal ControlSkin controlSkin;
1577 internal void ApplyTheme ()
1580 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1581 string type_name = null;
1582 if (trace != null) {
1583 type_name = GetType ().Name;
1584 trace.Write ("control", String.Format ("ApplyThemeRecursive {0} {1}", _userId, type_name));
1587 if (Page.PageTheme != null && EnableTheming) {
1588 ControlSkin controlSkin = Page.PageTheme.GetControlSkin (GetType (), SkinID);
1589 if (controlSkin != null)
1590 controlSkin.ApplySkin (this);
1595 trace.Write ("control", String.Format ("End ApplyThemeRecursive {0} {1}", _userId, type_name));
1600 internal bool AutoID
1602 get { return (stateMask & AUTOID) != 0; }
1604 if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
1607 SetMask (AUTOID, value);
1611 protected internal virtual void RemovedControl (Control control)
1613 control.UnloadRecursive (false);
1614 control._parent = null;
1615 control._page = null;
1616 control._namingContainer = null;
1622 string skinId = string.Empty;
1623 bool _enableTheming = true;
1627 [DefaultValue (true)]
1628 public virtual bool EnableTheming
1632 if ((stateMask & ENABLE_THEMING) != 0)
1633 return _enableTheming;
1635 if (_parent != null)
1636 return _parent.EnableTheming;
1642 SetMask (ENABLE_THEMING, true);
1643 _enableTheming = value;
1649 [Filterable (false)]
1650 public virtual string SkinID
1652 get { return skinId; }
1653 set { skinId = value; }
1656 ControlBuilder IControlBuilderAccessor.ControlBuilder {
1657 get {throw new NotImplementedException (); }
1660 IDictionary IControlDesignerAccessor.GetDesignModeState ()
1662 throw new NotImplementedException ();
1665 void IControlDesignerAccessor.SetDesignModeState (IDictionary designData)
1667 SetDesignModeState (designData);
1670 void IControlDesignerAccessor.SetOwnerControl (Control control)
1672 throw new NotImplementedException ();
1675 IDictionary IControlDesignerAccessor.UserData {
1676 get { throw new NotImplementedException (); }
1679 ExpressionBindingCollection expressionBindings;
1681 ExpressionBindingCollection IExpressionsAccessor.Expressions {
1683 if (expressionBindings == null)
1684 expressionBindings = new ExpressionBindingCollection ();
1685 return expressionBindings;
1689 bool IExpressionsAccessor.HasExpressions {
1691 return (expressionBindings != null && expressionBindings.Count > 0);
1695 public virtual void Focus()
1697 Page.SetFocus (this);
1700 protected internal virtual void LoadControlState (object state)
1704 protected internal virtual object SaveControlState ()
1709 protected virtual void DataBind (bool raiseOnDataBinding)
1711 bool foundDataItem = false;
1713 if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
1714 object o = DataBinder.GetDataItem (this, out foundDataItem);
1716 Page.PushDataItemContext (o);
1721 if (raiseOnDataBinding)
1722 OnDataBinding (EventArgs.Empty);
1727 Page.PopDataItemContext ();
1731 protected virtual IDictionary GetDesignModeState ()
1733 throw new NotImplementedException ();
1736 protected virtual void SetDesignModeState (IDictionary data)
1738 throw new NotImplementedException ();
1741 void IParserAccessor.AddParsedSubObject (object obj) {
1742 this.AddParsedSubObject (obj);
1745 DataBindingCollection IDataBindingsAccessor.DataBindings {
1747 if (dataBindings == null) {
1748 dataBindings = new DataBindingCollection ();
1750 return dataBindings;
1754 bool IDataBindingsAccessor.HasDataBindings {
1756 if (dataBindings != null && dataBindings.Count > 0) {