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;
142 defaultNameArray = new string [100];
143 for (int i = 0; i < 100; i++)
145 defaultNameArray [i] = String.Format ("ctl{0:D2}", i);
147 defaultNameArray [i] = "_ctl" + i;
153 stateMask = ENABLE_VIEWSTATE | VISIBLE | AUTOID | BINDING_CONTAINER | AUTO_EVENT_WIREUP;
154 if (this is INamingContainer)
155 stateMask |= IS_NAMING_CONTAINER;
159 [MonoTODO ("Not implemented, always returns null")]
160 protected ControlAdapter Adapter {
162 // for the time being, fool the
163 // Control machinery into thinking we
164 // don't have an Adapter. This will
165 // allow us to write all the rest of
166 // the Adapter handling code without
167 // having to worry about *having*
173 string _appRelativeTemplateSourceDirectory = null;
175 [EditorBrowsable (EditorBrowsableState.Advanced)]
177 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
178 public string AppRelativeTemplateSourceDirectory {
180 if (_appRelativeTemplateSourceDirectory != null)
181 return _appRelativeTemplateSourceDirectory;
183 string tempSrcDir = null;
185 TemplateControl templateControl = TemplateControl;
186 if (templateControl != null)
187 if (!string.IsNullOrEmpty (templateControl.AppRelativeVirtualPath))
188 tempSrcDir = VirtualPathUtility.GetDirectory (templateControl.AppRelativeVirtualPath, false);
190 _appRelativeTemplateSourceDirectory = (tempSrcDir != null) ? tempSrcDir : "~/";
191 return _appRelativeTemplateSourceDirectory;
193 [EditorBrowsable (EditorBrowsableState.Never)]
195 _appRelativeTemplateSourceDirectory = value;
196 _templateSourceDirectory = null;
202 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
203 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
204 public Control BindingContainer {
206 Control container = NamingContainer;
207 if (container != null && (container.stateMask & BINDING_CONTAINER) == 0)
208 container = container.BindingContainer;
213 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
215 [WebSysDescription ("An Identification of the control that is rendered.")]
216 public virtual string ClientID {
218 string client = UniqueID;
222 client = UniqueID2ClientID (client);
224 client = client.Replace (':', ClientIDSeparator);
233 internal string UniqueID2ClientID (string uniqueId)
235 return uniqueId.Replace (IdSeparator, ClientIDSeparator);
238 protected char ClientIDSeparator
240 char ClientIDSeparator
247 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
249 [WebSysDescription ("The child controls of this control.")]
250 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 {
282 get { return (((stateMask & ID_SET) != 0) ? _userId : null); }
295 protected char IdSeparator {
299 protected internal bool IsChildControlStateCleared {
300 get { return _isChildControlStateCleared; }
303 protected internal bool IsViewStateEnabled {
305 for (Control control = this; control != null; control = control.Parent)
306 if (!control.EnableViewState)
313 protected bool LoadViewStateByID {
314 get { return false; }
318 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
320 [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]
321 public virtual Control NamingContainer {
323 if (_namingContainer == null && _parent != null) {
324 if ((_parent.stateMask & IS_NAMING_CONTAINER) == 0)
325 _namingContainer = _parent.NamingContainer;
327 _namingContainer = _parent;
330 return _namingContainer;
334 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
336 [WebSysDescription ("The webpage that this control resides on.")]
340 public virtual Page Page { //DIT
343 if (NamingContainer != null)
344 _page = NamingContainer.Page;
345 else if (Parent != null)
351 set { _page = value; }
354 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
356 [WebSysDescription ("The parent control of this control.")]
357 public virtual Control Parent { //DIT
358 get { return _parent; }
361 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
362 [EditorBrowsable (EditorBrowsableState.Advanced), Browsable (false)]
363 [WebSysDescription ("The site this control is part of.")]
364 public ISite Site { //DIT
365 get { return _site; }
366 set { _site = value; }
371 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
372 public TemplateControl TemplateControl {
373 get { return TemplateControlInternal; }
375 [EditorBrowsable (EditorBrowsableState.Never)]
376 set { _templateControl = value; }
379 internal virtual TemplateControl TemplateControlInternal {
381 if (_templateControl != null)
382 return _templateControl;
384 return _parent.TemplateControl;
391 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
393 [WebSysDescription ("A virtual directory containing the parent of the control.")]
394 public virtual string TemplateSourceDirectory {
397 if (_templateSourceDirectory == null) {
398 TemplateControl tc = TemplateControl;
401 HttpContext ctx = Context;
403 _templateSourceDirectory = VirtualPathUtility.GetDirectory (ctx.Request.CurrentExecutionFilePath);
404 } else if (tc != this)
405 _templateSourceDirectory = tc.TemplateSourceDirectory;
407 if (_templateSourceDirectory == null && this is TemplateControl) {
408 string path = ((TemplateControl) this).AppRelativeVirtualPath;
411 // Pretend our application virtual root is "/" even if it isn't - we just
412 // want to get an absolute url out of relative one, without the real
413 // application root prepended to it.
414 string ret = VirtualPathUtility.GetDirectory (VirtualPathUtility.ToAbsolute (path, "/"));
415 int len = ret.Length;
418 if (ret [--len] == '/')
419 _templateSourceDirectory = ret.Substring (0, len);
421 _templateSourceDirectory = String.Empty;
423 if (_templateSourceDirectory == null)
424 _templateSourceDirectory = String.Empty;
427 return _templateSourceDirectory;
429 if (_templateSourceDirectory == null) {
430 HttpContext ctx = HttpContext.Current;
431 HttpRequest req = ctx != null ? ctx.Request : null;
433 _templateSourceDirectory = (_parent == null)
434 ? req != null ? VirtualPathUtility.RemoveTrailingSlash (
435 VirtualPathUtility.GetDirectory (
436 HttpContext.Current.Request.CurrentExecutionFilePath)) : String.Empty
437 : _parent.TemplateSourceDirectory;
439 return _templateSourceDirectory;
445 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
447 [WebSysDescription ("The unique ID of the control.")]
448 public virtual string UniqueID {
450 if (uniqueID != null)
453 if (NamingContainer == null)
458 string prefix = NamingContainer.UniqueID;
460 // For J2EE portlets we need to add the namespace to the ID.
461 if (NamingContainer == Page && Page.PortletNamespace != null)
462 prefix = Page.PortletNamespace;
465 if (NamingContainer == Page || prefix == null) {
471 uniqueID = prefix + IdSeparator + _userId;
473 uniqueID = prefix + ":" + _userId;
479 void SetMask (int m, bool val) {
486 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
487 [WebSysDescription ("Visiblity state of the control.")]
488 public virtual bool Visible {
490 if ((stateMask & VISIBLE) == 0)
494 return _parent.Visible;
500 if ((value && (stateMask & VISIBLE) == 0) ||
501 (!value && (stateMask & VISIBLE) != 0)) {
502 if (IsTrackingViewState)
503 stateMask |= VISIBLE_CHANGED;
506 SetMask (VISIBLE, value);
510 protected bool ChildControlsCreated {
511 get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
513 if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
514 if (_controls != null)
518 SetMask (CHILD_CONTROLS_CREATED, value);
523 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
524 protected virtual HttpContext Context { //DIT
527 if (_context != null)
530 return HttpContext.Current;
531 context = _parent.Context;
534 return HttpContext.Current;
538 protected EventHandlerList Events {
541 _events = new EventHandlerList ();
546 protected bool HasChildViewState {
547 get { return (pendingVS != null && pendingVS.Count > 0); }
550 protected bool IsTrackingViewState {
551 get { return ((stateMask & TRACK_VIEWSTATE) != 0); }
555 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
556 [WebSysDescription ("ViewState")]
557 protected virtual StateBag ViewState {
559 if (_viewState == null)
560 _viewState = new StateBag (ViewStateIgnoresCase);
562 if (IsTrackingViewState)
563 _viewState.TrackViewState ();
570 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
571 protected virtual bool ViewStateIgnoresCase {
572 get { return false; }
575 internal bool AutoEventWireup {
576 get { return (stateMask & AUTO_EVENT_WIREUP) != 0; }
577 set { SetMask (AUTO_EVENT_WIREUP, value); }
580 internal void SetBindingContainer (bool isBC)
582 SetMask (BINDING_CONTAINER, isBC);
585 internal void ResetChildNames ()
590 string GetDefaultName ()
593 if (defaultNumberID > 99) {
595 defaultName = "ctl" + defaultNumberID++;
597 defaultName = "_ctl" + defaultNumberID++;
600 defaultName = defaultNameArray [defaultNumberID++];
605 void NullifyUniqueID ()
611 for (int i = 0; i < _controls.Count; i++)
612 _controls [i].NullifyUniqueID ();
615 protected internal virtual void AddedControl (Control control, int index)
617 ResetControlsCache ();
619 /* Ensure the control don't have more than 1 parent */
620 if (control._parent != null)
621 control._parent.Controls.Remove (control);
623 control._parent = this;
624 Control nc = ((stateMask & IS_NAMING_CONTAINER) != 0) ? this : NamingContainer;
626 if ((stateMask & (INITING | INITED)) != 0)
627 control.InitRecursive (nc);
629 control.SetNamingContainer (nc);
633 if ((stateMask & (VIEWSTATE_LOADED | LOADED)) != 0) {
634 if (pendingVS != null) {
635 object vs = pendingVS [index];
637 pendingVS.Remove (index);
638 if (pendingVS.Count == 0)
641 control.LoadViewStateRecursive (vs);
646 if ((stateMask & LOADED) != 0)
647 control.LoadRecursive ();
649 if ((stateMask & PRERENDERED) != 0)
650 control.PreRenderRecursiveInternal ();
653 void SetNamingContainer (Control nc)
656 _namingContainer = nc;
662 protected virtual void AddParsedSubObject (object obj) //DIT
664 Control c = obj as Control;
670 [EditorBrowsable (EditorBrowsableState.Advanced)]
671 public virtual void ApplyStyleSheetSkin (Page page)
673 if (!EnableTheming) /* this enough? */
676 /* apply the style sheet skin here */
677 if (page.StyleSheetPageTheme != null) {
678 ControlSkin cs = page.StyleSheetPageTheme.GetControlSkin (GetType (), SkinID);
685 protected void BuildProfileTree (string parentId, bool calcViewState)
691 protected void ClearChildControlState ()
693 _isChildControlStateCleared = true;
696 protected void ClearChildState ()
698 ClearChildViewState ();
699 ClearChildControlState ();
703 protected void ClearChildViewState ()
713 virtual void CreateChildControls () //DIT
717 protected virtual ControlCollection CreateControlCollection () //DIT
719 return new ControlCollection (this);
722 protected virtual void EnsureChildControls ()
724 if (ChildControlsCreated == false && (stateMask & CREATING_CONTROLS) == 0) {
725 stateMask |= CREATING_CONTROLS;
728 Adapter.CreateChildControls ();
731 CreateChildControls ();
732 ChildControlsCreated = true;
733 stateMask &= ~CREATING_CONTROLS;
737 void EnsureIDInternal ()
742 _userId = NamingContainer.GetDefaultName ();
743 SetMask (AUTOID_SET, true);
747 protected void EnsureID ()
749 if (NamingContainer == null)
752 SetMask (ID_SET, true);
755 protected bool HasEvents ()
757 return _events != null;
761 void ResetControlsCache ()
763 _controlsCache = null;
765 if ((this.stateMask & IS_NAMING_CONTAINER) == 0 && Parent != null)
766 Parent.ResetControlsCache ();
769 Hashtable InitControlsCache ()
771 if (_controlsCache != null)
772 return _controlsCache;
774 if ((this.stateMask & IS_NAMING_CONTAINER) != 0 || Parent == null)
775 //LAMESPEC: MS' docs don't mention it, but FindControl is case insensitive.
777 _controlsCache = new Hashtable (StringComparer.OrdinalIgnoreCase);
779 _controlsCache = new Hashtable (CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);
782 _controlsCache = Parent.InitControlsCache ();
784 return _controlsCache;
787 void EnsureControlsCache ()
789 if (_controlsCache != null)
792 InitControlsCache ();
793 FillControlCache (this);
797 void FillControlCache (Control control)
802 foreach (Control c in control._controls) {
804 if (c._userId != null)
805 _controlsCache.Add (c._userId, c);
806 } catch (Exception ex) {
807 throw new HttpException ("Found more than one control with ID '" + c._userId + "'", ex);
810 if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ())
811 FillControlCache (c);
815 protected bool IsLiteralContent ()
817 if (HasControls () && _controls.Count == 1 && (_controls [0] is LiteralControl))
823 [WebSysDescription ("")]
824 public virtual Control FindControl (string id)
826 return FindControl (id, 0);
829 Control LookForControlByName (string id)
832 if (this == Page && id != null && id == Page.PortletNamespace)
835 EnsureControlsCache ();
836 return (Control) _controlsCache [id];
839 protected virtual Control FindControl (string id, int pathOffset)
841 EnsureChildControls ();
842 Control namingContainer = null;
843 if ((stateMask & IS_NAMING_CONTAINER) == 0) {
844 namingContainer = NamingContainer;
845 if (namingContainer == null)
848 return namingContainer.FindControl (id, pathOffset);
854 int separatorIdx = id.IndexOf (IdSeparator, pathOffset);
856 int separatorIdx = id.IndexOf (':', pathOffset);
858 if (separatorIdx == -1)
859 return LookForControlByName (id.Substring (pathOffset));
861 string idfound = id.Substring (pathOffset, separatorIdx - pathOffset);
862 namingContainer = LookForControlByName (idfound);
863 if (namingContainer == null)
866 return namingContainer.FindControl (id, separatorIdx + 1);
869 protected virtual void LoadViewState (object savedState)
871 if (savedState != null) {
872 ViewState.LoadViewState (savedState);
873 object o = ViewState ["Visible"];
875 SetMask (VISIBLE, (bool) o);
876 stateMask |= VISIBLE_CHANGED;
881 // [MonoTODO("Secure?")]
882 protected string MapPathSecure (string virtualPath)
884 string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
885 return Context.Request.MapPath (combined);
888 protected virtual bool OnBubbleEvent (object source, EventArgs args) //DIT
891 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
892 string type_name = null;
894 type_name = GetType ().Name;
895 trace.Write ("control", String.Format ("OnBubbleEvent {0} {1}", _userId, type_name));
901 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)
926 if ((event_mask & init_mask) != 0) {
927 EventHandler eh = (EventHandler) (_events [InitEvent]);
930 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
931 string type_name = null;
933 type_name = GetType ().Name;
934 trace.Write ("control", String.Format ("OnInit {0} {1}", _userId, type_name));
947 virtual void OnLoad (EventArgs e)
949 if ((event_mask & load_mask) != 0) {
950 EventHandler eh = (EventHandler) (_events [LoadEvent]);
953 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
954 string type_name = null;
956 type_name = GetType ().Name;
957 trace.Write ("control", String.Format ("OnLoad {0} {1}", _userId, type_name));
970 virtual void OnPreRender (EventArgs e)
972 if ((event_mask & prerender_mask) != 0) {
973 EventHandler eh = (EventHandler) (_events [PreRenderEvent]);
976 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
977 string type_name = null;
979 type_name = GetType ().Name;
980 trace.Write ("control", String.Format ("OnPreRender {0} {1}", _userId, type_name));
993 virtual void OnUnload (EventArgs e)
995 if ((event_mask & unload_mask) != 0) {
996 EventHandler eh = (EventHandler) (_events [UnloadEvent]);
999 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1000 string type_name = null;
1001 if (trace != null) {
1002 type_name = GetType ().Name;
1003 trace.Write ("control", String.Format ("OnUnload {0} {1}", _userId, type_name));
1012 protected internal Stream OpenFile (string path)
1015 string filePath = Context.Server.MapPath (path);
1016 return File.OpenRead (filePath);
1018 catch (UnauthorizedAccessException) {
1019 throw new HttpException ("Access to the specified file was denied.");
1023 internal string GetPhysicalFilePath (string virtualPath)
1027 if (VirtualPathUtility.IsAbsolute (virtualPath))
1028 return page != null ? page.MapPath (virtualPath) : Context.Server.MapPath (virtualPath);
1030 // We need to determine whether one of our parents is a
1031 // master page. If so, we need to map the path
1032 // relatively to the master page and not our containing
1033 // page/control. This is necessary for cases when a
1034 // relative path is used in a control placed in a master
1035 // page and the master page is referenced from a
1036 // location other than its own. In such cases MS.NET looks
1037 // for the file in the directory where the master page
1040 // An example of where it is needed is at
1042 // http://quickstarts.asp.net/QuickStartv20/aspnet/samples/masterpages/masterpages_cs/pages/default.aspx
1044 MasterPage master = null;
1045 Control ctrl = Parent;
1047 while (ctrl != null) {
1048 if (ctrl is MasterPage) {
1049 master = ctrl as MasterPage;
1057 path = VirtualPathUtility.Combine (master.TemplateSourceDirectory, virtualPath);
1059 path = VirtualPathUtility.Combine (TemplateSourceDirectory, virtualPath);
1060 return page != null ? page.MapPath (path) : Context.Server.MapPath (path);
1064 protected void RaiseBubbleEvent (object source, EventArgs args)
1069 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1070 string type_name = null;
1071 if (trace != null) {
1072 type_name = GetType ().Name;
1073 trace.Write ("control", String.Format ("RaiseBubbleEvent {0} {1}", _userId, type_name));
1076 if (c.OnBubbleEvent (source, args)) {
1079 trace.Write ("control", String.Format ("End RaiseBubbleEvent (false) {0} {1}", _userId, type_name));
1085 trace.Write ("control", String.Format ("End RaiseBubbleEvent (true) {0} {1}", _userId, type_name));
1096 virtual void Render (HtmlTextWriter writer) //DIT
1098 RenderChildren (writer);
1106 virtual void RenderChildren (HtmlTextWriter writer) //DIT
1108 if (_renderMethodDelegate != null) {
1109 _renderMethodDelegate (writer, this);
1110 } else if (_controls != null) {
1111 int len = _controls.Count;
1113 for (int i = 0; i < len; i++) {
1118 if (c.Adapter != null)
1119 c.RenderControl (writer, c.Adapter);
1122 c.RenderControl (writer);
1128 protected virtual ControlAdapter ResolveAdapter ()
1130 throw new NotImplementedException ();
1134 protected virtual object SaveViewState ()
1136 if ((stateMask & VISIBLE_CHANGED) != 0) {
1137 ViewState ["Visible"] = (stateMask & VISIBLE) != 0;
1138 } else if (_viewState == null) {
1142 return _viewState.SaveViewState ();
1145 protected virtual void TrackViewState ()
1147 if (_viewState != null)
1148 _viewState.TrackViewState ();
1150 stateMask |= TRACK_VIEWSTATE;
1153 public virtual void Dispose ()
1155 if ((event_mask & disposed_mask) != 0) {
1156 EventHandler eh = (EventHandler) (_events [DisposedEvent]);
1158 eh (this, EventArgs.Empty);
1162 [WebCategory ("FIXME")]
1163 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]
1164 public event EventHandler DataBinding {
1166 event_mask |= databinding_mask;
1167 Events.AddHandler (DataBindingEvent, value);
1169 remove { Events.RemoveHandler (DataBindingEvent, value); }
1172 [WebSysDescription ("Raised when the contol is disposed.")]
1173 public event EventHandler Disposed {
1175 event_mask |= disposed_mask;
1176 Events.AddHandler (DisposedEvent, value);
1178 remove { Events.RemoveHandler (DisposedEvent, value); }
1181 [WebSysDescription ("Raised when the page containing the control is initialized.")]
1182 public event EventHandler Init {
1184 event_mask |= init_mask;
1185 Events.AddHandler (InitEvent, value);
1187 remove { Events.RemoveHandler (InitEvent, value); }
1190 [WebSysDescription ("Raised after the page containing the control has been loaded.")]
1191 public event EventHandler Load {
1193 event_mask |= load_mask;
1194 Events.AddHandler (LoadEvent, value);
1196 remove { Events.RemoveHandler (LoadEvent, value); }
1199 [WebSysDescription ("Raised before the page containing the control is rendered.")]
1200 public event EventHandler PreRender {
1202 event_mask |= prerender_mask;
1203 Events.AddHandler (PreRenderEvent, value);
1205 remove { Events.RemoveHandler (PreRenderEvent, value); }
1208 [WebSysDescription ("Raised when the page containing the control is unloaded.")]
1209 public event EventHandler Unload {
1211 event_mask |= unload_mask;
1212 Events.AddHandler (UnloadEvent, value);
1214 remove { Events.RemoveHandler (UnloadEvent, value); }
1217 public virtual void DataBind () //DIT
1222 OnDataBinding (EventArgs.Empty);
1231 void DataBindChildren ()
1233 if (!HasControls ())
1236 int len = _controls.Count;
1237 for (int i = 0; i < len; i++) {
1238 Control c = _controls [i];
1243 public virtual bool HasControls ()
1245 return (_controls != null && _controls.Count > 0);
1253 void RenderControl (HtmlTextWriter writer)
1255 if ((stateMask & VISIBLE) != 0) {
1256 HttpContext ctx = Context;
1257 TraceContext trace = (ctx != null) ? ctx.Trace : null;
1259 if ((trace != null) && trace.IsEnabled)
1260 pos = ctx.Response.GetOutputByteCount ();
1263 if ((trace != null) && trace.IsEnabled) {
1264 int size = ctx.Response.GetOutputByteCount () - pos;
1265 trace.SaveSize (this, size >= 0 ? size : 0);
1271 protected void RenderControl (HtmlTextWriter writer, ControlAdapter adapter)
1273 if ((stateMask & VISIBLE) != 0) {
1274 adapter.BeginRender (writer);
1275 adapter.Render (writer);
1276 adapter.EndRender (writer);
1281 public string ResolveUrl (string relativeUrl)
1283 if (relativeUrl == null)
1284 throw new ArgumentNullException ("relativeUrl");
1286 if (relativeUrl == "")
1289 if (relativeUrl [0] == '#')
1292 string ts = TemplateSourceDirectory;
1293 if (ts == null || ts.Length == 0 ||
1294 Context == null || Context.Response == null ||
1295 !UrlUtils.IsRelativeUrl (relativeUrl))
1298 HttpResponse resp = Context.Response;
1299 return resp.ApplyAppPathModifier (UrlUtils.Combine (ts, relativeUrl));
1308 string ResolveClientUrl (string relativeUrl)
1311 // There are no relative paths when rendering a J2EE portlet
1312 if (Page != null && Page.PortletNamespace != null)
1313 return ResolveUrl (relativeUrl);
1315 if (relativeUrl == null)
1316 throw new ArgumentNullException ("relativeUrl");
1318 if (relativeUrl.Length == 0)
1319 return String.Empty;
1321 if (VirtualPathUtility.IsAbsolute (relativeUrl) || relativeUrl.IndexOf (':') >= 0)
1324 HttpContext context = Context;
1325 if (context != null && context.Request != null) {
1326 string templateSourceDirectory = TemplateSourceDirectory;
1327 if (templateSourceDirectory == null || templateSourceDirectory.Length == 0)
1330 string basePath = context.Request.CurrentExecutionFilePath;
1332 if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/')
1333 basePath = VirtualPathUtility.GetDirectory (basePath, false);
1335 if (VirtualPathUtility.IsAppRelative (relativeUrl))
1336 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1338 string templatePath = VirtualPathUtility.AppendTrailingSlash (templateSourceDirectory);
1340 if (basePath.Length == templatePath.Length && String.CompareOrdinal (basePath, templatePath) == 0)
1343 relativeUrl = VirtualPathUtility.Combine (templatePath, relativeUrl);
1344 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1349 internal bool HasRenderMethodDelegate ()
1351 return _renderMethodDelegate != null;
1354 [EditorBrowsable (EditorBrowsableState.Advanced)]
1355 public void SetRenderMethodDelegate (RenderMethod renderMethod) //DIT
1357 _renderMethodDelegate = renderMethod;
1360 internal void LoadRecursive ()
1363 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1364 string type_name = null;
1365 if (trace != null) {
1366 type_name = GetType ().Name;
1367 trace.Write ("control", String.Format ("LoadRecursive {0} {1}", _userId, type_name));
1371 if (Adapter != null)
1372 Adapter.OnLoad (EventArgs.Empty);
1375 OnLoad (EventArgs.Empty);
1376 if (HasControls ()) {
1377 int len = _controls.Count;
1378 for (int i = 0; i < len; i++) {
1379 Control c = _controls [i];
1386 trace.Write ("control", String.Format ("End LoadRecursive {0} {1}", _userId, type_name));
1388 stateMask |= LOADED;
1391 internal void UnloadRecursive (Boolean dispose)
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 ("UnloadRecursive {0} {1}", _userId, type_name));
1401 if (HasControls ()) {
1402 int len = _controls.Count;
1403 for (int i = 0; i < len; i++) {
1404 Control c = _controls [i];
1405 c.UnloadRecursive (dispose);
1411 trace.Write ("control", String.Format ("End UnloadRecursive {0} {1}", _userId, type_name));
1414 if (Adapter != null)
1415 Adapter.OnUnload (EventArgs.Empty);
1418 OnUnload (EventArgs.Empty);
1423 internal void PreRenderRecursiveInternal ()
1430 visible = (stateMask & VISIBLE) != 0;
1435 SetMask (VISIBLE, true);
1437 EnsureChildControls ();
1439 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1440 string type_name = null;
1441 if (trace != null) {
1442 type_name = GetType ().Name;
1443 trace.Write ("control", String.Format ("PreRenderRecursive {0} {1}", _userId, type_name));
1447 if (Adapter != null)
1448 Adapter.OnPreRender (EventArgs.Empty);
1451 OnPreRender (EventArgs.Empty);
1452 if (!HasControls ())
1455 int len = _controls.Count;
1456 for (int i = 0; i < len; i++) {
1457 Control c = _controls [i];
1458 c.PreRenderRecursiveInternal ();
1462 trace.Write ("control", String.Format ("End PreRenderRecursive {0} {1}", _userId, type_name));
1467 SetMask (VISIBLE, false);
1470 stateMask |= PRERENDERED;
1473 internal void InitRecursive (Control namingContainer)
1476 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1477 string type_name = null;
1478 if (trace != null) {
1479 type_name = GetType ().Name;
1480 trace.Write ("control", String.Format ("InitRecursive {0} {1}", _userId, type_name));
1483 SetNamingContainer (namingContainer);
1485 if (HasControls ()) {
1486 if ((stateMask & IS_NAMING_CONTAINER) != 0)
1487 namingContainer = this;
1489 int len = _controls.Count;
1490 for (int i = 0; i < len; i++) {
1491 Control c = _controls [i];
1492 c.InitRecursive (namingContainer);
1496 stateMask |= INITING;
1500 if (Adapter != null)
1501 Adapter.OnInit (EventArgs.Empty);
1504 OnInit (EventArgs.Empty);
1507 trace.Write ("control", String.Format ("End InitRecursive {0} {1}", _userId, type_name));
1510 stateMask |= INITED;
1511 stateMask &= ~INITING;
1514 internal object SaveViewStateRecursive ()
1516 if (!EnableViewState)
1520 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1521 string type_name = null;
1522 if (trace != null) {
1523 type_name = GetType ().Name;
1524 trace.Write ("control", String.Format ("SaveViewStateRecursive {0} {1}", _userId, type_name));
1528 ArrayList controlList = null;
1529 ArrayList controlStates = null;
1532 if (HasControls ()) {
1533 int len = _controls.Count;
1534 for (int i = 0; i < len; i++) {
1535 Control ctrl = _controls [i];
1536 object ctrlState = ctrl.SaveViewStateRecursive ();
1538 if (ctrlState == null)
1541 if (controlList == null) {
1542 controlList = new ArrayList ();
1543 controlStates = new ArrayList ();
1546 controlList.Add (idx);
1547 controlStates.Add (ctrlState);
1551 object thisState = SaveViewState ();
1552 if (thisState == null && controlList == null && controlStates == null) {
1554 if (trace != null) {
1555 trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved nothing", _userId, type_name));
1556 trace.SaveViewState (this, null);
1563 if (trace != null) {
1564 trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved a Triplet", _userId, type_name));
1565 trace.SaveViewState (this, thisState);
1568 return new Triplet (thisState, controlList, controlStates);
1571 internal void LoadViewStateRecursive (object savedState)
1573 if (!EnableViewState || savedState == null)
1577 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1578 string type_name = null;
1579 if (trace != null) {
1580 type_name = GetType ().Name;
1581 trace.Write ("control", String.Format ("LoadViewStateRecursive {0} {1}", _userId, type_name));
1584 Triplet savedInfo = (Triplet) savedState;
1585 LoadViewState (savedInfo.First);
1587 ArrayList controlList = savedInfo.Second as ArrayList;
1588 if (controlList == null)
1590 ArrayList controlStates = savedInfo.Third as ArrayList;
1591 int nControls = controlList.Count;
1592 for (int i = 0; i < nControls; i++) {
1593 int k = (int) controlList [i];
1594 if (k < Controls.Count && controlStates != null) {
1595 Control c = Controls [k];
1596 c.LoadViewStateRecursive (controlStates [i]);
1599 if (pendingVS == null)
1600 pendingVS = new Hashtable ();
1602 pendingVS [k] = controlStates [i];
1608 trace.Write ("control", String.Format ("End LoadViewStateRecursive {0} {1}", _userId, type_name));
1610 stateMask |= VIEWSTATE_LOADED;
1614 internal ControlSkin controlSkin;
1616 internal void ApplyTheme ()
1619 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1620 string type_name = null;
1621 if (trace != null) {
1622 type_name = GetType ().Name;
1623 trace.Write ("control", String.Format ("ApplyThemeRecursive {0} {1}", _userId, type_name));
1626 if (Page.PageTheme != null && EnableTheming) {
1627 ControlSkin controlSkin = Page.PageTheme.GetControlSkin (GetType (), SkinID);
1628 if (controlSkin != null)
1629 controlSkin.ApplySkin (this);
1634 trace.Write ("control", String.Format ("End ApplyThemeRecursive {0} {1}", _userId, type_name));
1639 internal bool AutoID {
1640 get { return (stateMask & AUTOID) != 0; }
1642 if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
1645 SetMask (AUTOID, value);
1649 protected internal virtual void RemovedControl (Control control)
1651 control.UnloadRecursive (false);
1652 control._parent = null;
1653 control._page = null;
1654 control._namingContainer = null;
1655 if ((control.stateMask & AUTOID_SET) != 0) {
1656 control._userId = null;
1657 control.SetMask (ID_SET, false);
1659 control.NullifyUniqueID ();
1663 string skinId = string.Empty;
1664 bool _enableTheming = true;
1668 [DefaultValue (true)]
1669 public virtual bool EnableTheming {
1671 if ((stateMask & ENABLE_THEMING) != 0)
1672 return _enableTheming;
1674 if (_parent != null)
1675 return _parent.EnableTheming;
1680 SetMask (ENABLE_THEMING, true);
1681 _enableTheming = value;
1687 [Filterable (false)]
1688 public virtual string SkinID {
1689 get { return skinId; }
1690 set { skinId = value; }
1693 ControlBuilder IControlBuilderAccessor.ControlBuilder {
1694 get { throw new NotImplementedException (); }
1697 IDictionary IControlDesignerAccessor.GetDesignModeState ()
1699 throw new NotImplementedException ();
1702 void IControlDesignerAccessor.SetDesignModeState (IDictionary designData)
1704 SetDesignModeState (designData);
1707 void IControlDesignerAccessor.SetOwnerControl (Control control)
1709 throw new NotImplementedException ();
1712 IDictionary IControlDesignerAccessor.UserData {
1713 get { throw new NotImplementedException (); }
1716 ExpressionBindingCollection expressionBindings;
1718 ExpressionBindingCollection IExpressionsAccessor.Expressions {
1720 if (expressionBindings == null)
1721 expressionBindings = new ExpressionBindingCollection ();
1722 return expressionBindings;
1726 bool IExpressionsAccessor.HasExpressions {
1727 get { return (expressionBindings != null && expressionBindings.Count > 0); }
1730 public virtual void Focus ()
1732 Page.SetFocus (this);
1735 protected internal virtual void LoadControlState (object state)
1739 protected internal virtual object SaveControlState ()
1744 protected virtual void DataBind (bool raiseOnDataBinding)
1746 bool foundDataItem = false;
1748 if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
1749 object o = DataBinder.GetDataItem (this, out foundDataItem);
1751 Page.PushDataItemContext (o);
1755 if (raiseOnDataBinding)
1756 OnDataBinding (EventArgs.Empty);
1757 DataBindChildren ();
1760 Page.PopDataItemContext ();
1764 protected virtual IDictionary GetDesignModeState ()
1766 throw new NotImplementedException ();
1769 protected virtual void SetDesignModeState (IDictionary data)
1771 throw new NotImplementedException ();
1774 void IParserAccessor.AddParsedSubObject (object obj)
1776 this.AddParsedSubObject (obj);
1779 DataBindingCollection IDataBindingsAccessor.DataBindings {
1781 if (dataBindings == null) {
1782 dataBindings = new DataBindingCollection ();
1784 return dataBindings;
1788 bool IDataBindingsAccessor.HasDataBindings {
1790 if (dataBindings != null && dataBindings.Count > 0) {