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;
103 Hashtable _controlsCache;
106 DataBindingCollection dataBindings;
107 Hashtable pendingVS; // may hold unused viewstate data from child controls
111 TemplateControl _templateControl;
112 bool _isChildControlStateCleared;
114 string _templateSourceDirectory;
118 const int ENABLE_VIEWSTATE = 1;
119 const int VISIBLE = 1 << 1;
120 const int AUTOID = 1 << 2;
121 const int CREATING_CONTROLS = 1 << 3;
122 const int BINDING_CONTAINER = 1 << 4;
123 const int AUTO_EVENT_WIREUP = 1 << 5;
124 const int IS_NAMING_CONTAINER = 1 << 6;
125 const int VISIBLE_CHANGED = 1 << 7;
126 const int TRACK_VIEWSTATE = 1 << 8;
127 const int CHILD_CONTROLS_CREATED = 1 << 9;
128 const int ID_SET = 1 << 10;
129 const int INITED = 1 << 11;
130 const int INITING = 1 << 12;
131 const int VIEWSTATE_LOADED = 1 << 13;
132 const int LOADED = 1 << 14;
133 const int PRERENDERED = 1 << 15;
135 const int ENABLE_THEMING = 1 << 16;
137 const int AUTOID_SET = 1 << 17;
141 defaultNameArray = new string [100];
142 for (int i = 0; i < 100; i++)
144 defaultNameArray [i] = String.Format ("ctl{0:D2}", i);
146 defaultNameArray [i] = "_ctl" + i;
151 stateMask = ENABLE_VIEWSTATE | VISIBLE | AUTOID | BINDING_CONTAINER | AUTO_EVENT_WIREUP;
152 if (this is INamingContainer)
153 stateMask |= IS_NAMING_CONTAINER;
157 [MonoTODO ("Not implemented, always returns null")]
158 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 {
178 if (_appRelativeTemplateSourceDirectory != null)
179 return _appRelativeTemplateSourceDirectory;
181 string tempSrcDir = null;
183 TemplateControl templateControl = TemplateControl;
184 if (templateControl != null)
185 if (!string.IsNullOrEmpty (templateControl.AppRelativeVirtualPath))
186 tempSrcDir = VirtualPathUtility.GetDirectory (templateControl.AppRelativeVirtualPath, false);
188 _appRelativeTemplateSourceDirectory = (tempSrcDir != null) ? tempSrcDir : "~/";
189 return _appRelativeTemplateSourceDirectory;
191 [EditorBrowsable (EditorBrowsableState.Never)]
193 _appRelativeTemplateSourceDirectory = value;
194 _templateSourceDirectory = null;
200 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
201 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
202 public Control BindingContainer {
204 Control container = NamingContainer;
205 if (container != null && (container.stateMask & BINDING_CONTAINER) == 0)
206 container = container.BindingContainer;
211 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
213 [WebSysDescription ("An Identification of the control that is rendered.")]
214 public virtual string ClientID {
216 string client = UniqueID;
220 client = UniqueID2ClientID (client);
222 client = client.Replace (':', ClientIDSeparator);
231 internal string UniqueID2ClientID (string uniqueId) {
232 return uniqueId.Replace (IdSeparator, ClientIDSeparator);
235 protected char ClientIDSeparator
237 char ClientIDSeparator
246 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
248 [WebSysDescription ("The child controls of this control.")]
249 public virtual ControlCollection Controls //DIT
252 if (_controls == null)
253 _controls = CreateControlCollection ();
259 [MonoTODO ("revisit once we have a real design strategy")]
260 protected internal bool DesignMode {
261 get { return false; }
265 [DefaultValue (true), WebCategory ("Behavior")]
266 [WebSysDescription ("An Identification of the control that is rendered.")]
270 public virtual bool EnableViewState {
271 get { return ((stateMask & ENABLE_VIEWSTATE) != 0); }
272 set { SetMask (ENABLE_VIEWSTATE, value); }
275 [MergableProperty (false), ParenthesizePropertyName (true)]
276 [WebSysDescription ("The name of the control that is rendered.")]
278 [Filterable (false), Themeable (false)]
281 public virtual string ID {
283 return (((stateMask & ID_SET) != 0) ? _userId : null);
297 protected char IdSeparator {
303 protected internal bool IsChildControlStateCleared {
304 get { return _isChildControlStateCleared; }
307 protected internal bool IsViewStateEnabled {
310 for (Control control = this; control != null; control = control.Parent)
311 if (!control.EnableViewState)
318 protected bool LoadViewStateByID {
325 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
327 [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]
328 public virtual Control NamingContainer {
330 if (_namingContainer == null && _parent != null) {
331 if ((_parent.stateMask & IS_NAMING_CONTAINER) == 0)
332 _namingContainer = _parent.NamingContainer;
334 _namingContainer = _parent;
337 return _namingContainer;
341 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
343 [WebSysDescription ("The webpage that this control resides on.")]
347 public virtual Page Page //DIT
351 if (NamingContainer != null)
352 _page = NamingContainer.Page;
353 else if (Parent != null)
363 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
365 [WebSysDescription ("The parent control of this control.")]
366 public virtual Control Parent //DIT
373 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
374 [EditorBrowsable (EditorBrowsableState.Advanced), Browsable (false)]
375 [WebSysDescription ("The site this control is part of.")]
376 public ISite Site //DIT
388 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
389 public TemplateControl TemplateControl {
391 return TemplateControlInternal;
394 [EditorBrowsable (EditorBrowsableState.Never)]
395 set { _templateControl = value; }
398 internal virtual TemplateControl TemplateControlInternal {
400 if (_templateControl != null)
401 return _templateControl;
403 return _parent.TemplateControl;
410 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
412 [WebSysDescription ("A virtual directory containing the parent of the control.")]
413 public virtual string TemplateSourceDirectory {
416 if (_templateSourceDirectory == null) {
417 TemplateControl tc = TemplateControl;
420 HttpContext ctx = Context;
422 _templateSourceDirectory = VirtualPathUtility.GetDirectory (ctx.Request.CurrentExecutionFilePath);
425 _templateSourceDirectory = tc.TemplateSourceDirectory;
427 if (_templateSourceDirectory == null && this is TemplateControl) {
428 string path = ((TemplateControl) this).AppRelativeVirtualPath;
431 // Pretend our application virtual root is "/" even if it isn't - we just
432 // want to get an absolute url out of relative one, without the real
433 // application root prepended to it.
434 string ret = VirtualPathUtility.GetDirectory (VirtualPathUtility.ToAbsolute (path, "/"));
435 int len = ret.Length;
438 if (ret [--len] == '/')
439 _templateSourceDirectory = ret.Substring (0, len);
442 _templateSourceDirectory = String.Empty;
444 if (_templateSourceDirectory == null)
445 _templateSourceDirectory = String.Empty;
448 return _templateSourceDirectory;
450 if (_templateSourceDirectory == null) {
451 HttpContext ctx = HttpContext.Current;
452 HttpRequest req = ctx != null ? ctx.Request : null;
454 _templateSourceDirectory = (_parent == null)
455 ? req != null ? VirtualPathUtility.RemoveTrailingSlash (
456 VirtualPathUtility.GetDirectory (
457 HttpContext.Current.Request.CurrentExecutionFilePath)) : String.Empty
458 : _parent.TemplateSourceDirectory;
460 return _templateSourceDirectory;
466 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
468 [WebSysDescription ("The unique ID of the control.")]
469 public virtual string UniqueID {
471 if (uniqueID != null)
474 if (NamingContainer == null)
479 string prefix = NamingContainer.UniqueID;
481 // For J2EE portlets we need to add the namespace to the ID.
482 if (NamingContainer == Page && Page.PortletNamespace != null)
483 prefix = Page.PortletNamespace;
486 if (NamingContainer == Page || prefix == null) {
492 uniqueID = prefix + IdSeparator + _userId;
494 uniqueID = prefix + ":" + _userId;
500 void SetMask (int m, bool val) {
507 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
508 [WebSysDescription ("Visiblity state of the control.")]
509 public virtual bool Visible {
511 if ((stateMask & VISIBLE) == 0)
515 return _parent.Visible;
521 if ((value && (stateMask & VISIBLE) == 0) ||
522 (!value && (stateMask & VISIBLE) != 0)) {
523 if (IsTrackingViewState)
524 stateMask |= VISIBLE_CHANGED;
527 SetMask (VISIBLE, value);
531 protected bool ChildControlsCreated {
532 get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
534 if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
535 if (_controls != null)
539 SetMask (CHILD_CONTROLS_CREATED, value);
544 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
545 protected virtual HttpContext Context //DIT
549 if (_context != null)
552 return HttpContext.Current;
553 context = _parent.Context;
556 return HttpContext.Current;
560 protected EventHandlerList Events {
563 _events = new EventHandlerList ();
568 protected bool HasChildViewState {
570 return (pendingVS != null && pendingVS.Count > 0);
574 protected bool IsTrackingViewState {
575 get { return ((stateMask & TRACK_VIEWSTATE) != 0); }
579 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
580 [WebSysDescription ("ViewState")]
581 protected virtual StateBag ViewState {
583 if (_viewState == null)
584 _viewState = new StateBag (ViewStateIgnoresCase);
586 if (IsTrackingViewState)
587 _viewState.TrackViewState ();
594 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
595 protected virtual bool ViewStateIgnoresCase {
601 internal bool AutoEventWireup {
602 get { return (stateMask & AUTO_EVENT_WIREUP) != 0; }
603 set { SetMask (AUTO_EVENT_WIREUP, value); }
606 internal void SetBindingContainer (bool isBC) {
607 SetMask (BINDING_CONTAINER, isBC);
610 internal void ResetChildNames () {
614 string GetDefaultName () {
616 if (defaultNumberID > 99) {
618 defaultName = "ctl" + defaultNumberID++;
620 defaultName = "_ctl" + defaultNumberID++;
624 defaultName = defaultNameArray [defaultNumberID++];
629 void NullifyUniqueID () {
634 for (int i = 0; i < _controls.Count; i++)
635 _controls [i].NullifyUniqueID ();
638 protected internal virtual void AddedControl (Control control, int index) {
639 ResetControlsCache ();
641 /* Ensure the control don't have more than 1 parent */
642 if (control._parent != null)
643 control._parent.Controls.Remove (control);
645 control._parent = this;
646 Control nc = ((stateMask & IS_NAMING_CONTAINER) != 0) ? this : NamingContainer;
648 if ((stateMask & (INITING | INITED)) != 0)
649 control.InitRecursive (nc);
651 control.SetNamingContainer (nc);
655 if ((stateMask & (VIEWSTATE_LOADED | LOADED)) != 0) {
656 if (pendingVS != null) {
657 object vs = pendingVS [index];
659 pendingVS.Remove (index);
660 if (pendingVS.Count == 0)
663 control.LoadViewStateRecursive (vs);
668 if ((stateMask & LOADED) != 0)
669 control.LoadRecursive ();
671 if ((stateMask & PRERENDERED) != 0)
672 control.PreRenderRecursiveInternal ();
675 void SetNamingContainer (Control nc) {
677 _namingContainer = nc;
683 protected virtual void AddParsedSubObject (object obj) //DIT
685 Control c = obj as Control;
691 [EditorBrowsable (EditorBrowsableState.Advanced)]
692 public virtual void ApplyStyleSheetSkin (Page page) {
693 if (!EnableTheming) /* this enough? */
696 /* apply the style sheet skin here */
697 if (page.StyleSheetPageTheme != null) {
698 ControlSkin cs = page.StyleSheetPageTheme.GetControlSkin (GetType (), SkinID);
705 protected void BuildProfileTree (string parentId, bool calcViewState) {
710 protected void ClearChildControlState () {
711 _isChildControlStateCleared = true;
714 protected void ClearChildState () {
715 ClearChildViewState ();
716 ClearChildControlState ();
720 protected void ClearChildViewState () {
729 virtual void CreateChildControls () { } //DIT
731 protected virtual ControlCollection CreateControlCollection () //DIT
733 return new ControlCollection (this);
736 protected virtual void EnsureChildControls () {
737 if (ChildControlsCreated == false && (stateMask & CREATING_CONTROLS) == 0) {
738 stateMask |= CREATING_CONTROLS;
741 Adapter.CreateChildControls ();
744 CreateChildControls ();
745 ChildControlsCreated = true;
746 stateMask &= ~CREATING_CONTROLS;
750 void EnsureIDInternal () {
754 _userId = NamingContainer.GetDefaultName ();
755 SetMask (AUTOID_SET, true);
759 protected void EnsureID () {
760 if (NamingContainer == null)
763 SetMask (ID_SET, true);
766 protected bool HasEvents () {
767 return _events != null;
772 internal void ResetControlsCache ()
774 _controlsCache = null;
776 if ((this.stateMask & IS_NAMING_CONTAINER) == 0 && Parent != null)
777 Parent.ResetControlsCache ();
780 internal Hashtable InitControlsCache ()
782 if (_controlsCache != null)
783 return _controlsCache;
785 if ((this.stateMask & IS_NAMING_CONTAINER) != 0 || Parent == null)
786 _controlsCache = new Hashtable ();
788 _controlsCache = Parent.InitControlsCache ();
790 return _controlsCache;
793 void EnsureControlsCache ()
795 if (_controlsCache != null)
798 InitControlsCache ();
799 FillControlCache (this);
803 void FillControlCache (Control control)
808 foreach (Control c in control._controls) {
810 if (c._userId != null)
811 _controlsCache.Add (c._userId, c);
813 catch (Exception ex) {
814 throw new HttpException ("Found more than one control with ID '" + c._userId + "'", ex);
817 if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ())
818 FillControlCache (c);
822 protected bool IsLiteralContent () {
823 if (HasControls () && _controls.Count == 1 && (_controls [0] is LiteralControl))
829 [WebSysDescription ("")]
830 public virtual Control FindControl (string id) {
831 return FindControl (id, 0);
834 Control LookForControlByName (string id) {
836 if (this == Page && id != null && id == Page.PortletNamespace)
839 EnsureControlsCache ();
840 return (Control) _controlsCache [id];
843 protected virtual Control FindControl (string id, int pathOffset) {
844 EnsureChildControls ();
845 Control namingContainer = null;
846 if ((stateMask & IS_NAMING_CONTAINER) == 0) {
847 namingContainer = NamingContainer;
848 if (namingContainer == null)
851 return namingContainer.FindControl (id, pathOffset);
857 int separatorIdx = id.IndexOf (IdSeparator, pathOffset);
859 int separatorIdx = id.IndexOf (':', pathOffset);
861 if (separatorIdx == -1)
862 return LookForControlByName (id.Substring (pathOffset));
864 string idfound = id.Substring (pathOffset, separatorIdx - pathOffset);
865 namingContainer = LookForControlByName (idfound);
866 if (namingContainer == null)
869 return namingContainer.FindControl (id, separatorIdx + 1);
872 protected virtual void LoadViewState (object savedState) {
873 if (savedState != null) {
874 ViewState.LoadViewState (savedState);
875 object o = ViewState ["Visible"];
877 SetMask (VISIBLE, (bool) o);
878 stateMask |= VISIBLE_CHANGED;
883 // [MonoTODO("Secure?")]
884 protected string MapPathSecure (string virtualPath) {
885 string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
886 return Context.Request.MapPath (combined);
889 protected virtual bool OnBubbleEvent (object source, EventArgs args) //DIT
892 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
893 string type_name = null;
895 type_name = GetType ().Name;
896 trace.Write ("control", String.Format ("OnBubbleEvent {0} {1}", _userId, type_name));
902 protected virtual void OnDataBinding (EventArgs e) {
903 if ((event_mask & databinding_mask) != 0) {
904 EventHandler eh = (EventHandler) (_events [DataBindingEvent]);
907 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
908 string type_name = null;
910 type_name = GetType ().Name;
911 trace.Write ("control", String.Format ("OnDataBinding {0} {1}", _userId, type_name));
924 virtual void OnInit (EventArgs e) {
925 if ((event_mask & init_mask) != 0) {
926 EventHandler eh = (EventHandler) (_events [InitEvent]);
929 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
930 string type_name = null;
932 type_name = GetType ().Name;
933 trace.Write ("control", String.Format ("OnInit {0} {1}", _userId, type_name));
946 virtual void OnLoad (EventArgs e) {
947 if ((event_mask & load_mask) != 0) {
948 EventHandler eh = (EventHandler) (_events [LoadEvent]);
951 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
952 string type_name = null;
954 type_name = GetType ().Name;
955 trace.Write ("control", String.Format ("OnLoad {0} {1}", _userId, type_name));
968 virtual void OnPreRender (EventArgs e) {
969 if ((event_mask & prerender_mask) != 0) {
970 EventHandler eh = (EventHandler) (_events [PreRenderEvent]);
973 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
974 string type_name = null;
976 type_name = GetType ().Name;
977 trace.Write ("control", String.Format ("OnPreRender {0} {1}", _userId, type_name));
990 virtual void OnUnload (EventArgs e) {
991 if ((event_mask & unload_mask) != 0) {
992 EventHandler eh = (EventHandler) (_events [UnloadEvent]);
995 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
996 string type_name = null;
998 type_name = GetType ().Name;
999 trace.Write ("control", String.Format ("OnUnload {0} {1}", _userId, type_name));
1008 protected internal Stream OpenFile (string path) {
1010 string filePath = Context.Server.MapPath (path);
1011 return File.OpenRead (filePath);
1013 catch (UnauthorizedAccessException) {
1014 throw new HttpException ("Access to the specified file was denied.");
1018 internal string GetPhysicalFilePath (string virtualPath) {
1021 if (VirtualPathUtility.IsAbsolute (virtualPath))
1022 return page != null ? page.MapPath (virtualPath) : Context.Server.MapPath (virtualPath);
1024 // We need to determine whether one of our parents is a
1025 // master page. If so, we need to map the path
1026 // relatively to the master page and not our containing
1027 // page/control. This is necessary for cases when a
1028 // relative path is used in a control placed in a master
1029 // page and the master page is referenced from a
1030 // location other than its own. In such cases MS.NET looks
1031 // for the file in the directory where the master page
1034 // An example of where it is needed is at
1036 // http://quickstarts.asp.net/QuickStartv20/aspnet/samples/masterpages/masterpages_cs/pages/default.aspx
1038 MasterPage master = null;
1039 Control ctrl = Parent;
1041 while (ctrl != null) {
1042 if (ctrl is MasterPage) {
1043 master = ctrl as MasterPage;
1051 path = VirtualPathUtility.Combine (master.TemplateSourceDirectory, virtualPath);
1053 path = VirtualPathUtility.Combine (TemplateSourceDirectory, virtualPath);
1054 return page != null ? page.MapPath (path) : Context.Server.MapPath (path);
1058 protected void RaiseBubbleEvent (object source, EventArgs args) {
1062 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1063 string type_name = null;
1064 if (trace != null) {
1065 type_name = GetType ().Name;
1066 trace.Write ("control", String.Format ("RaiseBubbleEvent {0} {1}", _userId, type_name));
1069 if (c.OnBubbleEvent (source, args)) {
1072 trace.Write ("control", String.Format ("End RaiseBubbleEvent (false) {0} {1}", _userId, type_name));
1078 trace.Write ("control", String.Format ("End RaiseBubbleEvent (true) {0} {1}", _userId, type_name));
1089 virtual void Render (HtmlTextWriter writer) //DIT
1091 RenderChildren (writer);
1099 virtual void RenderChildren (HtmlTextWriter writer) //DIT
1101 if (_renderMethodDelegate != null) {
1102 _renderMethodDelegate (writer, this);
1104 else if (_controls != null) {
1105 int len = _controls.Count;
1107 for (int i = 0; i < len; i++) {
1112 if (c.Adapter != null)
1113 c.RenderControl (writer, c.Adapter);
1116 c.RenderControl (writer);
1122 protected virtual ControlAdapter ResolveAdapter () {
1123 throw new NotImplementedException ();
1127 protected virtual object SaveViewState () {
1128 if ((stateMask & VISIBLE_CHANGED) != 0) {
1129 ViewState ["Visible"] = (stateMask & VISIBLE) != 0;
1131 else if (_viewState == null) {
1135 return _viewState.SaveViewState ();
1138 protected virtual void TrackViewState () {
1139 if (_viewState != null)
1140 _viewState.TrackViewState ();
1142 stateMask |= TRACK_VIEWSTATE;
1145 public virtual void Dispose () {
1146 if ((event_mask & disposed_mask) != 0) {
1147 EventHandler eh = (EventHandler) (_events [DisposedEvent]);
1149 eh (this, EventArgs.Empty);
1153 [WebCategory ("FIXME")]
1154 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]
1155 public event EventHandler DataBinding {
1157 event_mask |= databinding_mask;
1158 Events.AddHandler (DataBindingEvent, value);
1160 remove { Events.RemoveHandler (DataBindingEvent, value); }
1163 [WebSysDescription ("Raised when the contol is disposed.")]
1164 public event EventHandler Disposed {
1166 event_mask |= disposed_mask;
1167 Events.AddHandler (DisposedEvent, value);
1169 remove { Events.RemoveHandler (DisposedEvent, value); }
1172 [WebSysDescription ("Raised when the page containing the control is initialized.")]
1173 public event EventHandler Init {
1175 event_mask |= init_mask;
1176 Events.AddHandler (InitEvent, value);
1178 remove { Events.RemoveHandler (InitEvent, value); }
1181 [WebSysDescription ("Raised after the page containing the control has been loaded.")]
1182 public event EventHandler Load {
1184 event_mask |= load_mask;
1185 Events.AddHandler (LoadEvent, value);
1187 remove { Events.RemoveHandler (LoadEvent, value); }
1190 [WebSysDescription ("Raised before the page containing the control is rendered.")]
1191 public event EventHandler PreRender {
1193 event_mask |= prerender_mask;
1194 Events.AddHandler (PreRenderEvent, value);
1196 remove { Events.RemoveHandler (PreRenderEvent, value); }
1199 [WebSysDescription ("Raised when the page containing the control is unloaded.")]
1200 public event EventHandler Unload {
1202 event_mask |= unload_mask;
1203 Events.AddHandler (UnloadEvent, value);
1205 remove { Events.RemoveHandler (UnloadEvent, value); }
1208 public virtual void DataBind () //DIT
1213 OnDataBinding (EventArgs.Empty);
1222 void DataBindChildren () {
1223 if (!HasControls ())
1226 int len = _controls.Count;
1227 for (int i = 0; i < len; i++) {
1228 Control c = _controls [i];
1234 public virtual bool HasControls () {
1235 return (_controls != null && _controls.Count > 0);
1243 void RenderControl (HtmlTextWriter writer) {
1244 if ((stateMask & VISIBLE) != 0) {
1245 HttpContext ctx = Context;
1246 TraceContext trace = (ctx != null) ? ctx.Trace : null;
1248 if ((trace != null) && trace.IsEnabled)
1249 pos = ctx.Response.GetOutputByteCount ();
1252 if ((trace != null) && trace.IsEnabled) {
1253 int size = ctx.Response.GetOutputByteCount () - pos;
1254 trace.SaveSize (this, size >= 0 ? size : 0);
1260 protected void RenderControl (HtmlTextWriter writer,
1261 ControlAdapter adapter) {
1262 if ((stateMask & VISIBLE) != 0) {
1263 adapter.BeginRender (writer);
1264 adapter.Render (writer);
1265 adapter.EndRender (writer);
1270 public string ResolveUrl (string relativeUrl) {
1271 if (relativeUrl == null)
1272 throw new ArgumentNullException ("relativeUrl");
1274 if (relativeUrl == "")
1277 if (relativeUrl [0] == '#')
1280 string ts = TemplateSourceDirectory;
1281 if (ts == null || ts.Length == 0 ||
1282 Context == null || Context.Response == null ||
1283 !UrlUtils.IsRelativeUrl (relativeUrl))
1286 HttpResponse resp = Context.Response;
1287 return resp.ApplyAppPathModifier (UrlUtils.Combine (ts, relativeUrl));
1296 string ResolveClientUrl (string relativeUrl) {
1298 // There are no relative paths when rendering a J2EE portlet
1299 if (Page != null && Page.PortletNamespace != null)
1300 return ResolveUrl (relativeUrl);
1302 if (relativeUrl == null)
1303 throw new ArgumentNullException ("relativeUrl");
1305 if (relativeUrl.Length == 0)
1306 return String.Empty;
1308 if (VirtualPathUtility.IsAbsolute (relativeUrl) || relativeUrl.IndexOf (':') >= 0)
1311 HttpContext context = Context;
1312 if (context != null && context.Request != null) {
1313 string templateSourceDirectory = TemplateSourceDirectory;
1314 if (templateSourceDirectory == null || templateSourceDirectory.Length == 0)
1317 string basePath = context.Request.CurrentExecutionFilePath;
1319 if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/')
1320 basePath = VirtualPathUtility.GetDirectory (basePath, false);
1322 if (VirtualPathUtility.IsAppRelative (relativeUrl))
1323 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1325 string templatePath = VirtualPathUtility.AppendTrailingSlash (templateSourceDirectory);
1327 if (basePath.Length == templatePath.Length && String.CompareOrdinal (basePath, templatePath) == 0)
1330 relativeUrl = VirtualPathUtility.Combine (templatePath, relativeUrl);
1331 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1336 internal bool HasRenderMethodDelegate () {
1337 return _renderMethodDelegate != null;
1340 [EditorBrowsable (EditorBrowsableState.Advanced)]
1341 public void SetRenderMethodDelegate (RenderMethod renderMethod) //DIT
1343 _renderMethodDelegate = renderMethod;
1346 internal void LoadRecursive () {
1348 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1349 string type_name = null;
1350 if (trace != null) {
1351 type_name = GetType ().Name;
1352 trace.Write ("control", String.Format ("LoadRecursive {0} {1}", _userId, type_name));
1356 if (Adapter != null)
1357 Adapter.OnLoad (EventArgs.Empty);
1360 OnLoad (EventArgs.Empty);
1361 if (HasControls ()) {
1362 int len = _controls.Count;
1363 for (int i = 0; i < len; i++) {
1364 Control c = _controls [i];
1371 trace.Write ("control", String.Format ("End LoadRecursive {0} {1}", _userId, type_name));
1373 stateMask |= LOADED;
1376 internal void UnloadRecursive (Boolean dispose) {
1378 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1379 string type_name = null;
1380 if (trace != null) {
1381 type_name = GetType ().Name;
1382 trace.Write ("control", String.Format ("UnloadRecursive {0} {1}", _userId, type_name));
1385 if (HasControls ()) {
1386 int len = _controls.Count;
1387 for (int i = 0; i < len; i++) {
1388 Control c = _controls [i];
1389 c.UnloadRecursive (dispose);
1395 trace.Write ("control", String.Format ("End UnloadRecursive {0} {1}", _userId, type_name));
1398 if (Adapter != null)
1399 Adapter.OnUnload (EventArgs.Empty);
1402 OnUnload (EventArgs.Empty);
1407 internal void PreRenderRecursiveInternal () {
1408 if ((stateMask & VISIBLE) != 0) {
1409 EnsureChildControls ();
1411 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1412 string type_name = null;
1413 if (trace != null) {
1414 type_name = GetType ().Name;
1415 trace.Write ("control", String.Format ("PreRenderRecursive {0} {1}", _userId, type_name));
1419 if (Adapter != null)
1420 Adapter.OnPreRender (EventArgs.Empty);
1423 OnPreRender (EventArgs.Empty);
1424 if (!HasControls ())
1427 int len = _controls.Count;
1428 for (int i = 0; i < len; i++) {
1429 Control c = _controls [i];
1430 c.PreRenderRecursiveInternal ();
1434 trace.Write ("control", String.Format ("End PreRenderRecursive {0} {1}", _userId, type_name));
1437 stateMask |= PRERENDERED;
1440 internal void InitRecursive (Control namingContainer) {
1442 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1443 string type_name = null;
1444 if (trace != null) {
1445 type_name = GetType ().Name;
1446 trace.Write ("control", String.Format ("InitRecursive {0} {1}", _userId, type_name));
1449 SetNamingContainer (namingContainer);
1451 if (HasControls ()) {
1452 if ((stateMask & IS_NAMING_CONTAINER) != 0)
1453 namingContainer = this;
1455 int len = _controls.Count;
1456 for (int i = 0; i < len; i++) {
1457 Control c = _controls [i];
1458 c.InitRecursive (namingContainer);
1462 stateMask |= INITING;
1466 if (Adapter != null)
1467 Adapter.OnInit (EventArgs.Empty);
1470 OnInit (EventArgs.Empty);
1473 trace.Write ("control", String.Format ("End InitRecursive {0} {1}", _userId, type_name));
1476 stateMask |= INITED;
1477 stateMask &= ~INITING;
1480 internal object SaveViewStateRecursive () {
1481 if (!EnableViewState)
1485 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1486 string type_name = null;
1487 if (trace != null) {
1488 type_name = GetType ().Name;
1489 trace.Write ("control", String.Format ("SaveViewStateRecursive {0} {1}", _userId, type_name));
1493 ArrayList controlList = null;
1494 ArrayList controlStates = null;
1497 if (HasControls ()) {
1498 int len = _controls.Count;
1499 for (int i = 0; i < len; i++) {
1500 Control ctrl = _controls [i];
1501 object ctrlState = ctrl.SaveViewStateRecursive ();
1503 if (ctrlState == null)
1506 if (controlList == null) {
1507 controlList = new ArrayList ();
1508 controlStates = new ArrayList ();
1511 controlList.Add (idx);
1512 controlStates.Add (ctrlState);
1516 object thisState = SaveViewState ();
1517 if (thisState == null && controlList == null && controlStates == null) {
1519 if (trace != null) {
1520 trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved nothing", _userId, type_name));
1521 trace.SaveViewState (this, null);
1528 if (trace != null) {
1529 trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved a Triplet", _userId, type_name));
1530 trace.SaveViewState (this, thisState);
1533 return new Triplet (thisState, controlList, controlStates);
1536 internal void LoadViewStateRecursive (object savedState) {
1537 if (!EnableViewState || savedState == null)
1541 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1542 string type_name = null;
1543 if (trace != null) {
1544 type_name = GetType ().Name;
1545 trace.Write ("control", String.Format ("LoadViewStateRecursive {0} {1}", _userId, type_name));
1548 Triplet savedInfo = (Triplet) savedState;
1549 LoadViewState (savedInfo.First);
1551 ArrayList controlList = savedInfo.Second as ArrayList;
1552 if (controlList == null)
1554 ArrayList controlStates = savedInfo.Third as ArrayList;
1555 int nControls = controlList.Count;
1556 for (int i = 0; i < nControls; i++) {
1557 int k = (int) controlList [i];
1558 if (k < Controls.Count && controlStates != null) {
1559 Control c = Controls [k];
1560 c.LoadViewStateRecursive (controlStates [i]);
1563 if (pendingVS == null)
1564 pendingVS = new Hashtable ();
1566 pendingVS [k] = controlStates [i];
1572 trace.Write ("control", String.Format ("End LoadViewStateRecursive {0} {1}", _userId, type_name));
1574 stateMask |= VIEWSTATE_LOADED;
1578 internal ControlSkin controlSkin;
1580 internal void ApplyTheme () {
1582 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1583 string type_name = null;
1584 if (trace != null) {
1585 type_name = GetType ().Name;
1586 trace.Write ("control", String.Format ("ApplyThemeRecursive {0} {1}", _userId, type_name));
1589 if (Page.PageTheme != null && EnableTheming) {
1590 ControlSkin controlSkin = Page.PageTheme.GetControlSkin (GetType (), SkinID);
1591 if (controlSkin != null)
1592 controlSkin.ApplySkin (this);
1597 trace.Write ("control", String.Format ("End ApplyThemeRecursive {0} {1}", _userId, type_name));
1602 internal bool AutoID {
1603 get { return (stateMask & AUTOID) != 0; }
1605 if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
1608 SetMask (AUTOID, value);
1612 protected internal virtual void RemovedControl (Control control) {
1613 control.UnloadRecursive (false);
1614 control._parent = null;
1615 control._page = null;
1616 control._namingContainer = null;
1617 if ((control.stateMask & AUTOID_SET) != 0) {
1618 control._userId = null;
1619 control.SetMask (ID_SET, false);
1621 control.NullifyUniqueID ();
1627 string skinId = string.Empty;
1628 bool _enableTheming = true;
1632 [DefaultValue (true)]
1633 public virtual bool EnableTheming {
1635 if ((stateMask & ENABLE_THEMING) != 0)
1636 return _enableTheming;
1638 if (_parent != null)
1639 return _parent.EnableTheming;
1644 SetMask (ENABLE_THEMING, true);
1645 _enableTheming = value;
1651 [Filterable (false)]
1652 public virtual string SkinID {
1653 get { return skinId; }
1654 set { skinId = value; }
1657 ControlBuilder IControlBuilderAccessor.ControlBuilder {
1658 get { throw new NotImplementedException (); }
1661 IDictionary IControlDesignerAccessor.GetDesignModeState () {
1662 throw new NotImplementedException ();
1665 void IControlDesignerAccessor.SetDesignModeState (IDictionary designData) {
1666 SetDesignModeState (designData);
1669 void IControlDesignerAccessor.SetOwnerControl (Control control) {
1670 throw new NotImplementedException ();
1673 IDictionary IControlDesignerAccessor.UserData {
1674 get { throw new NotImplementedException (); }
1677 ExpressionBindingCollection expressionBindings;
1679 ExpressionBindingCollection IExpressionsAccessor.Expressions {
1681 if (expressionBindings == null)
1682 expressionBindings = new ExpressionBindingCollection ();
1683 return expressionBindings;
1687 bool IExpressionsAccessor.HasExpressions {
1689 return (expressionBindings != null && expressionBindings.Count > 0);
1693 public virtual void Focus () {
1694 Page.SetFocus (this);
1697 protected internal virtual void LoadControlState (object state) {
1700 protected internal virtual object SaveControlState () {
1704 protected virtual void DataBind (bool raiseOnDataBinding) {
1705 bool foundDataItem = false;
1707 if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
1708 object o = DataBinder.GetDataItem (this, out foundDataItem);
1710 Page.PushDataItemContext (o);
1715 if (raiseOnDataBinding)
1716 OnDataBinding (EventArgs.Empty);
1717 DataBindChildren ();
1722 Page.PopDataItemContext ();
1726 protected virtual IDictionary GetDesignModeState () {
1727 throw new NotImplementedException ();
1730 protected virtual void SetDesignModeState (IDictionary data) {
1731 throw new NotImplementedException ();
1734 void IParserAccessor.AddParsedSubObject (object obj) {
1735 this.AddParsedSubObject (obj);
1738 DataBindingCollection IDataBindingsAccessor.DataBindings {
1740 if (dataBindings == null) {
1741 dataBindings = new DataBindingCollection ();
1743 return dataBindings;
1747 bool IDataBindingsAccessor.HasDataBindings {
1749 if (dataBindings != null && dataBindings.Count > 0) {