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 using System.Collections;
37 using System.ComponentModel;
38 using System.ComponentModel.Design;
39 using System.ComponentModel.Design.Serialization;
40 using System.Security.Permissions;
42 using System.Web.Util;
43 using System.Globalization;
45 using System.Web.UI.Adapters;
49 namespace System.Web.UI
52 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
53 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
55 [DefaultProperty ("ID"), DesignerCategory ("Code"), ToolboxItemFilter ("System.Web.UI", ToolboxItemFilterType.Require)]
56 [ToolboxItem ("System.Web.UI.Design.WebControlToolboxItem, " + Consts.AssemblySystem_Design)]
57 [Designer ("System.Web.UI.Design.ControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
59 [DesignerSerializer ("Microsoft.VisualStudio.Web.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VisualStudio_Web,
60 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
64 [DesignerSerializer ("Microsoft.VSDesigner.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VSDesigner,
65 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
67 public partial class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor
69 , IUrlResolutionService, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor
72 internal static readonly object DataBindingEvent = new object ();
73 internal static readonly object DisposedEvent = new object ();
74 internal static readonly object InitEvent = new object ();
75 internal static readonly object LoadEvent = new object ();
76 internal static readonly object PreRenderEvent = new object ();
77 internal static readonly object UnloadEvent = new object ();
78 internal static string [] defaultNameArray;
81 const int databinding_mask = 1;
82 const int disposed_mask = 1 << 1;
83 const int init_mask = 1 << 2;
84 const int load_mask = 1 << 3;
85 const int prerender_mask = 1 << 4;
86 const int unload_mask = 1 << 5;
91 ControlCollection _controls;
92 Control _namingContainer;
97 EventHandlerList _events;
98 RenderMethod _renderMethodDelegate;
99 Hashtable _controlsCache;
102 DataBindingCollection dataBindings;
103 Hashtable pendingVS; // may hold unused viewstate data from child controls
107 TemplateControl _templateControl;
108 bool _isChildControlStateCleared;
110 string _templateSourceDirectory;
114 const int ENABLE_VIEWSTATE = 1;
115 const int VISIBLE = 1 << 1;
116 const int AUTOID = 1 << 2;
117 const int CREATING_CONTROLS = 1 << 3;
118 const int BINDING_CONTAINER = 1 << 4;
119 const int AUTO_EVENT_WIREUP = 1 << 5;
120 const int IS_NAMING_CONTAINER = 1 << 6;
121 const int VISIBLE_CHANGED = 1 << 7;
122 const int TRACK_VIEWSTATE = 1 << 8;
123 const int CHILD_CONTROLS_CREATED = 1 << 9;
124 const int ID_SET = 1 << 10;
125 const int INITED = 1 << 11;
126 const int INITING = 1 << 12;
127 const int VIEWSTATE_LOADED = 1 << 13;
128 const int LOADED = 1 << 14;
129 const int PRERENDERED = 1 << 15;
131 const int ENABLE_THEMING = 1 << 16;
133 const int AUTOID_SET = 1 << 17;
138 defaultNameArray = new string [100];
139 for (int i = 0; i < 100; i++)
141 defaultNameArray [i] = String.Concat ("ctl", i.ToString ("D2"));
143 defaultNameArray [i] = "_ctl" + i;
149 stateMask = ENABLE_VIEWSTATE | VISIBLE | AUTOID | BINDING_CONTAINER | AUTO_EVENT_WIREUP;
150 if (this is INamingContainer)
151 stateMask |= IS_NAMING_CONTAINER;
155 ControlAdapter adapter;
156 bool did_adapter_lookup;
157 protected internal ControlAdapter Adapter {
159 if (!did_adapter_lookup) {
160 adapter = ResolveAdapter ();
162 adapter.Control = this;
163 did_adapter_lookup = true;
169 string _appRelativeTemplateSourceDirectory = null;
171 [EditorBrowsable (EditorBrowsableState.Advanced)]
173 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
174 public string AppRelativeTemplateSourceDirectory {
176 if (_appRelativeTemplateSourceDirectory != null)
177 return _appRelativeTemplateSourceDirectory;
179 string tempSrcDir = null;
181 TemplateControl templateControl = TemplateControl;
182 if (templateControl != null)
183 if (!string.IsNullOrEmpty (templateControl.AppRelativeVirtualPath))
184 tempSrcDir = VirtualPathUtility.GetDirectory (templateControl.AppRelativeVirtualPath, false);
186 _appRelativeTemplateSourceDirectory = (tempSrcDir != null) ? tempSrcDir : "~/";
187 return _appRelativeTemplateSourceDirectory;
189 [EditorBrowsable (EditorBrowsableState.Never)]
191 _appRelativeTemplateSourceDirectory = value;
192 _templateSourceDirectory = null;
198 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
199 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
200 public Control BindingContainer {
202 Control container = NamingContainer;
203 if (container != null && (container.stateMask & BINDING_CONTAINER) == 0)
204 container = container.BindingContainer;
209 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
211 [WebSysDescription ("An Identification of the control that is rendered.")]
212 public virtual string ClientID {
214 string client = UniqueID;
218 client = UniqueID2ClientID (client);
220 client = client.Replace (':', ClientIDSeparator);
229 internal string UniqueID2ClientID (string uniqueId)
231 return uniqueId.Replace (IdSeparator, ClientIDSeparator);
234 protected char ClientIDSeparator
236 char ClientIDSeparator
243 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
245 [WebSysDescription ("The child controls of this control.")]
246 public virtual ControlCollection Controls { //DIT
248 if (_controls == null)
249 _controls = CreateControlCollection ();
255 [MonoTODO ("revisit once we have a real design strategy")]
256 protected internal bool DesignMode {
257 get { return false; }
261 [DefaultValue (true), WebCategory ("Behavior")]
262 [WebSysDescription ("An Identification of the control that is rendered.")]
266 public virtual bool EnableViewState {
267 get { return ((stateMask & ENABLE_VIEWSTATE) != 0); }
268 set { SetMask (ENABLE_VIEWSTATE, value); }
271 [MergableProperty (false), ParenthesizePropertyName (true)]
272 [WebSysDescription ("The name of the control that is rendered.")]
274 [Filterable (false), Themeable (false)]
277 public virtual string ID {
278 get { return (((stateMask & ID_SET) != 0) ? _userId : null); }
291 protected internal bool IsChildControlStateCleared {
292 get { return _isChildControlStateCleared; }
295 protected internal bool IsViewStateEnabled {
297 for (Control control = this; control != null; control = control.Parent)
298 if (!control.EnableViewState)
305 protected bool LoadViewStateByID {
306 get { return false; }
309 protected char IdSeparator {
313 internal char IdSeparator {
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 string ret = VirtualPathUtility.GetDirectory (VirtualPathUtility.ToAbsolute (path));
412 int len = ret.Length;
415 if (ret [--len] == '/')
416 _templateSourceDirectory = ret.Substring (0, len);
418 _templateSourceDirectory = String.Empty;
420 if (_templateSourceDirectory == null)
421 _templateSourceDirectory = String.Empty;
424 return _templateSourceDirectory;
426 if (_templateSourceDirectory == null) {
427 HttpContext ctx = HttpContext.Current;
428 HttpRequest req = ctx != null ? ctx.Request : null;
430 _templateSourceDirectory = (_parent == null)
431 ? req != null ? VirtualPathUtility.RemoveTrailingSlash (
432 VirtualPathUtility.GetDirectory (
433 HttpContext.Current.Request.CurrentExecutionFilePath)) : String.Empty
434 : _parent.TemplateSourceDirectory;
436 return _templateSourceDirectory;
442 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
444 [WebSysDescription ("The unique ID of the control.")]
445 public virtual string UniqueID {
447 if (uniqueID != null)
450 if (NamingContainer == null)
455 string prefix = NamingContainer.UniqueID;
456 if (NamingContainer == Page || prefix == null) {
459 if (getFacesContext () != null)
460 uniqueID = getFacesContext ().getExternalContext ().encodeNamespace (uniqueID);
465 uniqueID = prefix + IdSeparator + _userId;
470 void SetMask (int m, bool val) {
477 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
478 [WebSysDescription ("Visiblity state of the control.")]
479 public virtual bool Visible {
481 if ((stateMask & VISIBLE) == 0)
485 return _parent.Visible;
491 if ((value && (stateMask & VISIBLE) == 0) ||
492 (!value && (stateMask & VISIBLE) != 0)) {
493 if (IsTrackingViewState)
494 stateMask |= VISIBLE_CHANGED;
497 SetMask (VISIBLE, value);
501 protected bool ChildControlsCreated {
502 get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
504 if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
505 if (_controls != null)
509 SetMask (CHILD_CONTROLS_CREATED, value);
514 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
520 virtual HttpContext Context { //DIT
528 return HttpContext.Current;
529 HttpContext 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, Controls);
797 void FillControlCache (Control control, ControlCollection controls)
799 foreach (Control c in controls) {
801 if (c._userId != null)
802 control._controlsCache.Add (c._userId, c);
803 } catch (ArgumentException) {
804 throw new HttpException (
805 "Multiple controls with the same ID '" +
807 "' were found. FindControl requires that controls have unique IDs. ");
810 if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ())
811 control.FillControlCache (control, c.Controls);
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)
831 EnsureControlsCache ();
832 return (Control) _controlsCache [id];
835 protected virtual Control FindControl (string id, int pathOffset)
837 EnsureChildControls ();
838 Control namingContainer = null;
839 if ((stateMask & IS_NAMING_CONTAINER) == 0) {
840 namingContainer = NamingContainer;
841 if (namingContainer == null)
844 return namingContainer.FindControl (id, pathOffset);
850 int separatorIdx = id.IndexOf (IdSeparator, pathOffset);
851 if (separatorIdx == -1)
852 return LookForControlByName (id.Substring (pathOffset));
854 string idfound = id.Substring (pathOffset, separatorIdx - pathOffset);
855 namingContainer = LookForControlByName (idfound);
856 if (namingContainer == null)
859 return namingContainer.FindControl (id, separatorIdx + 1);
862 protected virtual void LoadViewState (object savedState)
864 if (savedState != null) {
865 ViewState.LoadViewState (savedState);
866 object o = ViewState ["Visible"];
868 SetMask (VISIBLE, (bool) o);
869 stateMask |= VISIBLE_CHANGED;
874 // [MonoTODO("Secure?")]
875 protected string MapPathSecure (string virtualPath)
877 string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
878 return Context.Request.MapPath (combined);
881 protected virtual bool OnBubbleEvent (object source, EventArgs args) //DIT
884 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
885 string type_name = null;
887 type_name = GetType ().Name;
888 trace.Write ("control", String.Concat ("OnBubbleEvent ", _userId, " ", type_name));
894 protected virtual void OnDataBinding (EventArgs e)
896 if ((event_mask & databinding_mask) != 0) {
897 EventHandler eh = (EventHandler) (_events [DataBindingEvent]);
900 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
901 string type_name = null;
903 type_name = GetType ().Name;
904 trace.Write ("control", String.Concat ("OnDataBinding ", _userId, " ", type_name));
917 virtual void OnInit (EventArgs e)
919 if ((event_mask & init_mask) != 0) {
920 EventHandler eh = (EventHandler) (_events [InitEvent]);
923 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
924 string type_name = null;
926 type_name = GetType ().Name;
927 trace.Write ("control", String.Concat ("OnInit ", _userId, " ", type_name));
940 virtual void OnLoad (EventArgs e)
942 if ((event_mask & load_mask) != 0) {
943 EventHandler eh = (EventHandler) (_events [LoadEvent]);
946 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
947 string type_name = null;
949 type_name = GetType ().Name;
950 trace.Write ("control", String.Concat ("OnLoad ", _userId, " ", type_name));
963 virtual void OnPreRender (EventArgs e)
965 if ((event_mask & prerender_mask) != 0) {
966 EventHandler eh = (EventHandler) (_events [PreRenderEvent]);
969 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
970 string type_name = null;
972 type_name = GetType ().Name;
973 trace.Write ("control", String.Concat ("OnPreRender ", _userId, " ", type_name));
986 virtual void OnUnload (EventArgs e)
988 if ((event_mask & unload_mask) != 0) {
989 EventHandler eh = (EventHandler) (_events [UnloadEvent]);
992 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
993 string type_name = null;
995 type_name = GetType ().Name;
996 trace.Write ("control", String.Concat ("OnUnload ", _userId, " ", type_name));
1005 protected internal Stream OpenFile (string path)
1008 string filePath = Context.Server.MapPath (path);
1009 return File.OpenRead (filePath);
1011 catch (UnauthorizedAccessException) {
1012 throw new HttpException ("Access to the specified file was denied.");
1016 internal string GetPhysicalFilePath (string virtualPath)
1020 if (VirtualPathUtility.IsAbsolute (virtualPath))
1021 return page != null ? page.MapPath (virtualPath) : Context.Server.MapPath (virtualPath);
1023 // We need to determine whether one of our parents is a
1024 // master page. If so, we need to map the path
1025 // relatively to the master page and not our containing
1026 // page/control. This is necessary for cases when a
1027 // relative path is used in a control placed in a master
1028 // page and the master page is referenced from a
1029 // location other than its own. In such cases MS.NET looks
1030 // for the file in the directory where the master page
1033 // An example of where it is needed is at
1035 // http://quickstarts.asp.net/QuickStartv20/aspnet/samples/masterpages/masterpages_cs/pages/default.aspx
1037 MasterPage master = null;
1038 Control ctrl = Parent;
1040 while (ctrl != null) {
1041 if (ctrl is MasterPage) {
1042 master = ctrl as MasterPage;
1050 path = VirtualPathUtility.Combine (master.TemplateSourceDirectory + "/", virtualPath);
1052 path = VirtualPathUtility.Combine (TemplateSourceDirectory + "/", virtualPath);
1054 return page != null ? page.MapPath (path) : Context.Server.MapPath (path);
1058 protected void RaiseBubbleEvent (object source, EventArgs args)
1063 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1064 string type_name = null;
1065 if (trace != null) {
1066 type_name = GetType ().Name;
1067 trace.Write ("control", String.Concat ("RaiseBubbleEvent ", _userId, " ", type_name));
1070 if (c.OnBubbleEvent (source, args)) {
1073 trace.Write ("control", String.Concat ("End RaiseBubbleEvent (false) ", _userId, " ", type_name));
1079 trace.Write ("control", String.Concat ("End RaiseBubbleEvent (true) ", _userId, " ", type_name));
1090 virtual void Render (HtmlTextWriter writer) //DIT
1092 RenderChildren (writer);
1100 virtual void RenderChildren (HtmlTextWriter writer) //DIT
1102 if (_renderMethodDelegate != null) {
1103 _renderMethodDelegate (writer, this);
1104 } else if (_controls != null) {
1105 int len = _controls.Count;
1107 for (int i = 0; i < len; i++) {
1112 ControlAdapter tmp = c.Adapter;
1114 c.RenderControl (writer, tmp);
1117 c.RenderControl (writer);
1123 protected virtual ControlAdapter ResolveAdapter ()
1125 HttpContext context = Context;
1127 if (context == null)
1130 if (!context.Request.BrowserMightHaveAdapters)
1133 // Search up the type hierarchy until we find a control with an adapter.
1134 IDictionary typeMap = context.Request.Browser.Adapters;
1135 Type controlType = GetType ();
1136 Type adapterType = (Type)typeMap [controlType];
1137 while (adapterType == null && controlType != typeof (Control)) {
1138 controlType = controlType.BaseType;
1139 adapterType = (Type)typeMap [controlType];
1142 ControlAdapter a = null;
1143 if (adapterType != null)
1144 a = (ControlAdapter)Activator.CreateInstance (adapterType);
1149 protected virtual object SaveViewState ()
1151 if ((stateMask & VISIBLE_CHANGED) != 0) {
1152 ViewState ["Visible"] = (stateMask & VISIBLE) != 0;
1153 } else if (_viewState == null) {
1157 return _viewState.SaveViewState ();
1160 protected virtual void TrackViewState ()
1162 if (_viewState != null)
1163 _viewState.TrackViewState ();
1165 stateMask |= TRACK_VIEWSTATE;
1168 public virtual void Dispose ()
1170 if ((event_mask & disposed_mask) != 0) {
1171 EventHandler eh = (EventHandler) (_events [DisposedEvent]);
1173 eh (this, EventArgs.Empty);
1177 [WebCategory ("FIXME")]
1178 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]
1179 public event EventHandler DataBinding {
1181 event_mask |= databinding_mask;
1182 Events.AddHandler (DataBindingEvent, value);
1184 remove { Events.RemoveHandler (DataBindingEvent, value); }
1187 [WebSysDescription ("Raised when the contol is disposed.")]
1188 public event EventHandler Disposed {
1190 event_mask |= disposed_mask;
1191 Events.AddHandler (DisposedEvent, value);
1193 remove { Events.RemoveHandler (DisposedEvent, value); }
1196 [WebSysDescription ("Raised when the page containing the control is initialized.")]
1197 public event EventHandler Init {
1199 event_mask |= init_mask;
1200 Events.AddHandler (InitEvent, value);
1202 remove { Events.RemoveHandler (InitEvent, value); }
1205 [WebSysDescription ("Raised after the page containing the control has been loaded.")]
1206 public event EventHandler Load {
1208 event_mask |= load_mask;
1209 Events.AddHandler (LoadEvent, value);
1211 remove { Events.RemoveHandler (LoadEvent, value); }
1214 [WebSysDescription ("Raised before the page containing the control is rendered.")]
1215 public event EventHandler PreRender {
1217 event_mask |= prerender_mask;
1218 Events.AddHandler (PreRenderEvent, value);
1220 remove { Events.RemoveHandler (PreRenderEvent, value); }
1223 [WebSysDescription ("Raised when the page containing the control is unloaded.")]
1224 public event EventHandler Unload {
1226 event_mask |= unload_mask;
1227 Events.AddHandler (UnloadEvent, value);
1229 remove { Events.RemoveHandler (UnloadEvent, value); }
1232 public virtual void DataBind () //DIT
1237 OnDataBinding (EventArgs.Empty);
1246 void DataBindChildren ()
1248 if (!HasControls ())
1251 int len = _controls.Count;
1252 for (int i = 0; i < len; i++) {
1253 Control c = _controls [i];
1258 public virtual bool HasControls ()
1260 return (_controls != null && _controls.Count > 0);
1268 void RenderControl (HtmlTextWriter writer)
1271 if (this.adapter != null) {
1272 RenderControl (writer, this.adapter);
1277 if ((stateMask & VISIBLE) != 0) {
1278 HttpContext ctx = Context;
1279 TraceContext trace = (ctx != null) ? ctx.Trace : null;
1281 if ((trace != null) && trace.IsEnabled)
1282 pos = ctx.Response.GetOutputByteCount ();
1285 if ((trace != null) && trace.IsEnabled) {
1286 int size = ctx.Response.GetOutputByteCount () - pos;
1287 trace.SaveSize (this, size >= 0 ? size : 0);
1293 protected void RenderControl (HtmlTextWriter writer, ControlAdapter adapter)
1295 if ((stateMask & VISIBLE) != 0) {
1296 adapter.BeginRender (writer);
1297 adapter.Render (writer);
1298 adapter.EndRender (writer);
1303 public string ResolveUrl (string relativeUrl)
1305 if (relativeUrl == null)
1306 throw new ArgumentNullException ("relativeUrl");
1308 if (relativeUrl == String.Empty)
1311 if (VirtualPathUtility.IsAbsolute (relativeUrl))
1314 if (relativeUrl [0] == '#')
1318 string ts = AppRelativeTemplateSourceDirectory;
1320 string ts = TemplateSourceDirectory;
1322 if (ts == null || ts.Length == 0 ||
1323 Context == null || Context.Response == null ||
1324 relativeUrl.IndexOf (':') >= 0)
1327 HttpResponse resp = Context.Response;
1328 if (!VirtualPathUtility.IsAppRelative (relativeUrl))
1329 relativeUrl = VirtualPathUtility.Combine (VirtualPathUtility.AppendTrailingSlash (ts), relativeUrl);
1330 return resp.ApplyAppPathModifier (relativeUrl);
1339 string ResolveClientUrl (string relativeUrl)
1341 if (relativeUrl == null)
1342 throw new ArgumentNullException ("relativeUrl");
1344 if (relativeUrl.Length == 0)
1345 return String.Empty;
1348 relativeUrl = ResolveClientUrlInternal (relativeUrl);
1350 javax.faces.context.FacesContext faces = getFacesContext ();
1355 if (relativeUrl.IndexOf (':') >= 0)
1356 url = ResolveAppRelativeFromFullPath (relativeUrl);
1357 else if (VirtualPathUtility.IsAbsolute (relativeUrl))
1358 url = VirtualPathUtility.ToAppRelative (relativeUrl);
1360 return faces.getApplication ().getViewHandler ().getResourceURL (faces, relativeUrl);
1362 if (VirtualPathUtility.IsAppRelative (url)) {
1363 url = url.Substring (1);
1364 url = url.Length == 0 ? "/" : url;
1365 return faces.getApplication ().getViewHandler ().getResourceURL (faces, url);
1370 string ResolveClientUrlInternal (string relativeUrl) {
1371 if (relativeUrl.StartsWith (J2EE.J2EEConsts.ACTION_URL_PREFIX, StringComparison.Ordinal))
1372 return CreateActionUrl (relativeUrl.Substring (J2EE.J2EEConsts.ACTION_URL_PREFIX.Length));
1374 if (relativeUrl.StartsWith (J2EE.J2EEConsts.RENDER_URL_PREFIX, StringComparison.Ordinal))
1375 return ResolveClientUrl (relativeUrl.Substring (J2EE.J2EEConsts.RENDER_URL_PREFIX.Length));
1378 if (VirtualPathUtility.IsAbsolute (relativeUrl) || relativeUrl.IndexOf (':') >= 0)
1381 HttpContext context = Context;
1382 if (context != null && context.Request != null) {
1383 string templateSourceDirectory = TemplateSourceDirectory;
1384 if (templateSourceDirectory == null || templateSourceDirectory.Length == 0)
1387 string basePath = context.Request.FilePath;
1389 if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/')
1390 basePath = VirtualPathUtility.GetDirectory (basePath, false);
1392 if (VirtualPathUtility.IsAppRelative (relativeUrl))
1393 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1395 string templatePath = VirtualPathUtility.AppendTrailingSlash (templateSourceDirectory);
1397 if (basePath.Length == templatePath.Length && String.CompareOrdinal (basePath, templatePath) == 0)
1400 relativeUrl = VirtualPathUtility.Combine (templatePath, relativeUrl);
1401 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1406 internal bool HasRenderMethodDelegate ()
1408 return _renderMethodDelegate != null;
1411 [EditorBrowsable (EditorBrowsableState.Advanced)]
1412 public void SetRenderMethodDelegate (RenderMethod renderMethod) //DIT
1414 _renderMethodDelegate = renderMethod;
1417 internal void LoadRecursive ()
1420 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1421 string type_name = null;
1422 if (trace != null) {
1423 type_name = GetType ().Name;
1424 trace.Write ("control", String.Concat ("LoadRecursive ", _userId, " ", type_name));
1428 if (Adapter != null)
1429 Adapter.OnLoad (EventArgs.Empty);
1432 OnLoad (EventArgs.Empty);
1433 if (HasControls ()) {
1434 int len = _controls.Count;
1435 for (int i = 0; i < len; i++) {
1436 Control c = _controls [i];
1443 trace.Write ("control", String.Concat ("End LoadRecursive ", _userId, " ", type_name));
1445 stateMask |= LOADED;
1448 internal void UnloadRecursive (Boolean dispose)
1451 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1452 string type_name = null;
1453 if (trace != null) {
1454 type_name = GetType ().Name;
1455 trace.Write ("control", String.Concat ("UnloadRecursive ", _userId, " ", type_name));
1458 if (HasControls ()) {
1459 int len = _controls.Count;
1460 for (int i = 0; i < len; i++) {
1461 Control c = _controls [i];
1462 c.UnloadRecursive (dispose);
1468 trace.Write ("control", String.Concat ("End UnloadRecursive ", _userId, " ", type_name));
1471 ControlAdapter tmp = Adapter;
1473 tmp.OnUnload (EventArgs.Empty);
1476 OnUnload (EventArgs.Empty);
1481 internal void PreRenderRecursiveInternal ()
1488 visible = (stateMask & VISIBLE) != 0;
1493 SetMask (VISIBLE, true);
1495 EnsureChildControls ();
1497 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1498 string type_name = null;
1499 if (trace != null) {
1500 type_name = GetType ().Name;
1501 trace.Write ("control", String.Concat ("PreRenderRecursive ", _userId, " ", type_name));
1505 if (Adapter != null)
1506 Adapter.OnPreRender (EventArgs.Empty);
1509 OnPreRender (EventArgs.Empty);
1510 if (!HasControls ())
1513 int len = _controls.Count;
1514 for (int i = 0; i < len; i++) {
1515 Control c = _controls [i];
1516 c.PreRenderRecursiveInternal ();
1520 trace.Write ("control", String.Concat ("End PreRenderRecursive ", _userId, " ", type_name));
1525 SetMask (VISIBLE, false);
1528 stateMask |= PRERENDERED;
1531 internal void InitRecursive (Control namingContainer)
1534 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1535 string type_name = null;
1536 if (trace != null) {
1537 type_name = GetType ().Name;
1538 trace.Write ("control", String.Concat ("InitRecursive ", _userId, " ", type_name));
1541 SetNamingContainer (namingContainer);
1543 if (HasControls ()) {
1544 if ((stateMask & IS_NAMING_CONTAINER) != 0)
1545 namingContainer = this;
1547 int len = _controls.Count;
1548 for (int i = 0; i < len; i++) {
1549 Control c = _controls [i];
1550 c.InitRecursive (namingContainer);
1554 stateMask |= INITING;
1557 ControlAdapter tmp = Adapter;
1559 tmp.OnInit (EventArgs.Empty);
1562 OnInit (EventArgs.Empty);
1565 trace.Write ("control", String.Concat ("End InitRecursive ", _userId, " ", type_name));
1568 stateMask |= INITED;
1569 stateMask &= ~INITING;
1572 internal object SaveViewStateRecursive ()
1574 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1576 string type_name = null;
1577 if (trace != null) {
1578 type_name = GetType ().Name;
1579 trace.Write ("control", String.Concat ("SaveViewStateRecursive ", _userId, " ", type_name));
1583 ArrayList controlList = null;
1584 ArrayList controlStates = null;
1587 if (HasControls ()) {
1588 int len = _controls.Count;
1589 for (int i = 0; i < len; i++) {
1590 Control ctrl = _controls [i];
1591 object ctrlState = ctrl.SaveViewStateRecursive ();
1593 if (ctrlState == null)
1596 if (controlList == null) {
1597 controlList = new ArrayList ();
1598 controlStates = new ArrayList ();
1601 controlList.Add (idx);
1602 controlStates.Add (ctrlState);
1607 object thisAdapterViewState = null;
1608 if (Adapter != null)
1609 thisAdapterViewState = Adapter.SaveAdapterViewState ();
1611 object thisState = SaveViewState ();
1613 if (thisState == null && controlList == null && controlStates == null) {
1614 if (trace != null) {
1616 trace.Write ("control", "End SaveViewStateRecursive " + _userId + " " + type_name + " saved nothing");
1618 trace.SaveViewState (this, null);
1623 if (trace != null) {
1625 trace.Write ("control", "End SaveViewStateRecursive " + _userId + " " + type_name + " saved a Triplet");
1627 trace.SaveViewState (this, thisState);
1630 thisState = new object[] { thisState, thisAdapterViewState };
1632 return new Triplet (thisState, controlList, controlStates);
1635 internal void LoadViewStateRecursive (object savedState)
1637 if (savedState == null)
1641 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1642 string type_name = null;
1643 if (trace != null) {
1644 type_name = GetType ().Name;
1645 trace.Write ("control", String.Concat ("LoadViewStateRecursive ", _userId, " ", type_name));
1648 Triplet savedInfo = (Triplet) savedState;
1650 object[] controlAndAdapterViewStates = (object [])savedInfo.First;
1651 if (Adapter != null)
1652 Adapter.LoadAdapterViewState (controlAndAdapterViewStates [1]);
1653 LoadViewState (controlAndAdapterViewStates [0]);
1655 LoadViewState (savedInfo.First);
1658 ArrayList controlList = savedInfo.Second as ArrayList;
1659 if (controlList == null)
1661 ArrayList controlStates = savedInfo.Third as ArrayList;
1662 int nControls = controlList.Count;
1663 for (int i = 0; i < nControls; i++) {
1664 int k = (int) controlList [i];
1665 if (k < Controls.Count && controlStates != null) {
1666 Control c = Controls [k];
1667 c.LoadViewStateRecursive (controlStates [i]);
1670 if (pendingVS == null)
1671 pendingVS = new Hashtable ();
1673 pendingVS [k] = controlStates [i];
1679 trace.Write ("control", String.Concat ("End LoadViewStateRecursive ", _userId, " ", type_name));
1681 stateMask |= VIEWSTATE_LOADED;
1685 internal ControlSkin controlSkin;
1687 internal void ApplyTheme ()
1690 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1691 string type_name = null;
1692 if (trace != null) {
1693 type_name = GetType ().Name;
1694 trace.Write ("control", String.Concat ("ApplyThemeRecursive ", _userId, " ", type_name));
1697 if (Page.PageTheme != null && EnableTheming) {
1698 ControlSkin controlSkin = Page.PageTheme.GetControlSkin (GetType (), SkinID);
1699 if (controlSkin != null)
1700 controlSkin.ApplySkin (this);
1705 trace.Write ("control", String.Concat ("End ApplyThemeRecursive ", _userId, " ", type_name));
1710 internal bool AutoID {
1711 get { return (stateMask & AUTOID) != 0; }
1713 if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
1716 SetMask (AUTOID, value);
1720 protected internal virtual void RemovedControl (Control control)
1722 control.UnloadRecursive (false);
1723 control._parent = null;
1724 control._page = null;
1725 control._namingContainer = null;
1726 if ((control.stateMask & AUTOID_SET) != 0) {
1727 control._userId = null;
1728 control.SetMask (ID_SET, false);
1730 control.NullifyUniqueID ();
1734 string skinId = string.Empty;
1735 bool _enableTheming = true;
1739 [DefaultValue (true)]
1740 public virtual bool EnableTheming {
1742 if ((stateMask & ENABLE_THEMING) != 0)
1743 return _enableTheming;
1745 if (_parent != null)
1746 return _parent.EnableTheming;
1751 SetMask (ENABLE_THEMING, true);
1752 _enableTheming = value;
1758 [Filterable (false)]
1759 public virtual string SkinID {
1760 get { return skinId; }
1761 set { skinId = value; }
1764 ControlBuilder IControlBuilderAccessor.ControlBuilder {
1765 get { throw new NotImplementedException (); }
1768 IDictionary IControlDesignerAccessor.GetDesignModeState ()
1770 throw new NotImplementedException ();
1773 void IControlDesignerAccessor.SetDesignModeState (IDictionary designData)
1775 SetDesignModeState (designData);
1778 void IControlDesignerAccessor.SetOwnerControl (Control control)
1780 throw new NotImplementedException ();
1783 IDictionary IControlDesignerAccessor.UserData {
1784 get { throw new NotImplementedException (); }
1787 ExpressionBindingCollection expressionBindings;
1789 ExpressionBindingCollection IExpressionsAccessor.Expressions {
1791 if (expressionBindings == null)
1792 expressionBindings = new ExpressionBindingCollection ();
1793 return expressionBindings;
1797 bool IExpressionsAccessor.HasExpressions {
1798 get { return (expressionBindings != null && expressionBindings.Count > 0); }
1801 public virtual void Focus ()
1803 Page.SetFocus (this);
1806 protected internal virtual void LoadControlState (object state)
1810 protected internal virtual object SaveControlState ()
1815 protected virtual void DataBind (bool raiseOnDataBinding)
1817 bool foundDataItem = false;
1819 if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
1820 object o = DataBinder.GetDataItem (this, out foundDataItem);
1822 Page.PushDataItemContext (o);
1826 if (raiseOnDataBinding)
1827 OnDataBinding (EventArgs.Empty);
1828 DataBindChildren ();
1831 Page.PopDataItemContext ();
1835 protected virtual IDictionary GetDesignModeState ()
1837 throw new NotImplementedException ();
1840 protected virtual void SetDesignModeState (IDictionary data)
1842 throw new NotImplementedException ();
1845 internal bool IsInited {
1846 get { return (stateMask & INITED) != 0; }
1849 internal bool IsLoaded {
1850 get { return (stateMask & LOADED) != 0; }
1853 internal bool IsPrerendered {
1854 get { return (stateMask & PRERENDERED) != 0; }
1857 bool CheckForValidationSupport ()
1859 return GetType ().GetCustomAttributes (typeof (SupportsEventValidationAttribute), false).Length > 0;
1863 // Apparently this is where .NET routes validation from all the controls which
1866 // http://odetocode.com/Blogs/scott/archive/2006/03/20/3145.aspx
1867 // Sample in here contains ValidateEvent in the stack trace
1869 // http://odetocode.com/blogs/scott/archive/2006/03/21/3153.aspx
1871 // http://www.alexthissen.nl/blogs/main/archive/2005/12/13/event-validation-of-controls-in-asp-net-2-0.aspx
1873 // It also seems that it's the control's responsibility to call this method or
1874 // validation won't take place. Also, the SupportsEventValidation attribute must be
1875 // present on the control for validation to take place.
1877 internal void ValidateEvent (String uniqueId, String argument)
1881 if (page != null && CheckForValidationSupport ())
1882 page.ClientScript.ValidateEvent (uniqueId, argument);
1885 void IParserAccessor.AddParsedSubObject (object obj)
1887 this.AddParsedSubObject (obj);
1890 DataBindingCollection IDataBindingsAccessor.DataBindings {
1892 if (dataBindings == null) {
1893 dataBindings = new DataBindingCollection ();
1895 return dataBindings;
1899 bool IDataBindingsAccessor.HasDataBindings {
1901 if (dataBindings != null && dataBindings.Count > 0) {