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)
9 // Marek Habersack <mhabersack@novell.com>
12 // (c) 2002,2003 Ximian, Inc. (http://www.ximian.com)
13 // (C) 2004-2010 Novell, Inc. (http://www.novell.com)
17 // Permission is hereby granted, free of charge, to any person obtaining
18 // a copy of this software and associated documentation files (the
19 // "Software"), to deal in the Software without restriction, including
20 // without limitation the rights to use, copy, modify, merge, publish,
21 // distribute, sublicense, and/or sell copies of the Software, and to
22 // permit persons to whom the Software is furnished to do so, subject to
23 // the following conditions:
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 using System.Collections;
38 using System.Collections.Generic;
39 using System.ComponentModel;
40 using System.ComponentModel.Design;
41 using System.ComponentModel.Design.Serialization;
42 using System.Globalization;
44 using System.Security.Permissions;
46 using System.Web.Util;
47 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")]
58 [DesignerSerializer ("Microsoft.VisualStudio.Web.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VisualStudio_Web,
59 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
62 public partial class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor, IUrlResolutionService, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor
64 internal static readonly object DataBindingEvent = new object ();
65 internal static readonly object DisposedEvent = new object ();
66 internal static readonly object InitEvent = new object ();
67 internal static readonly object LoadEvent = new object ();
68 internal static readonly object PreRenderEvent = new object ();
69 internal static readonly object UnloadEvent = new object ();
70 internal static string [] defaultNameArray;
73 const int databinding_mask = 1;
74 const int disposed_mask = 1 << 1;
75 const int init_mask = 1 << 2;
76 const int load_mask = 1 << 3;
77 const int prerender_mask = 1 << 4;
78 const int unload_mask = 1 << 5;
82 static Dictionary <Type, bool> loadViewStateByIDCache;
83 bool? loadViewStateByID;
86 ControlCollection _controls;
87 Control _namingContainer;
92 EventHandlerList _events;
93 RenderMethod _renderMethodDelegate;
94 Hashtable _controlsCache;
97 DataBindingCollection dataBindings;
98 Hashtable pendingVS; // may hold unused viewstate data from child controls
99 TemplateControl _templateControl;
100 bool _isChildControlStateCleared;
101 string _templateSourceDirectory;
105 const int ENABLE_VIEWSTATE = 1;
106 const int VISIBLE = 1 << 1;
107 const int AUTOID = 1 << 2;
108 const int CREATING_CONTROLS = 1 << 3;
109 const int BINDING_CONTAINER = 1 << 4;
110 const int AUTO_EVENT_WIREUP = 1 << 5;
111 const int IS_NAMING_CONTAINER = 1 << 6;
112 const int VISIBLE_CHANGED = 1 << 7;
113 const int TRACK_VIEWSTATE = 1 << 8;
114 const int CHILD_CONTROLS_CREATED = 1 << 9;
115 const int ID_SET = 1 << 10;
116 const int INITED = 1 << 11;
117 const int INITING = 1 << 12;
118 const int VIEWSTATE_LOADED = 1 << 13;
119 const int LOADED = 1 << 14;
120 const int PRERENDERED = 1 << 15;
121 const int ENABLE_THEMING = 1 << 16;
122 const int AUTOID_SET = 1 << 17;
123 const int REMOVED = 1 << 18;
128 defaultNameArray = new string [100];
129 for (int i = 0; i < 100; i++)
130 defaultNameArray [i] = String.Concat ("ctl", i.ToString ("D2"));
135 stateMask = ENABLE_VIEWSTATE | VISIBLE | AUTOID | BINDING_CONTAINER | AUTO_EVENT_WIREUP;
136 if (this is INamingContainer)
137 stateMask |= IS_NAMING_CONTAINER;
140 ControlAdapter adapter;
141 bool did_adapter_lookup;
142 protected internal ControlAdapter Adapter {
144 if (!did_adapter_lookup) {
145 adapter = ResolveAdapter ();
147 adapter.control = this;
148 did_adapter_lookup = true;
154 string _appRelativeTemplateSourceDirectory = null;
156 [EditorBrowsable (EditorBrowsableState.Advanced)]
158 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
159 public string AppRelativeTemplateSourceDirectory {
161 if (_appRelativeTemplateSourceDirectory != null)
162 return _appRelativeTemplateSourceDirectory;
164 string tempSrcDir = null;
165 TemplateControl templateControl = TemplateControl;
166 if (templateControl != null) {
167 string templateVirtualPath = templateControl.AppRelativeVirtualPath;
168 if (!String.IsNullOrEmpty (templateVirtualPath))
169 tempSrcDir = VirtualPathUtility.GetDirectory (templateVirtualPath, false);
172 _appRelativeTemplateSourceDirectory = (tempSrcDir != null) ? tempSrcDir : VirtualPathUtility.ToAppRelative (TemplateSourceDirectory);
173 return _appRelativeTemplateSourceDirectory;
175 [EditorBrowsable (EditorBrowsableState.Never)]
177 _appRelativeTemplateSourceDirectory = value;
178 _templateSourceDirectory = null;
182 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
183 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
184 public Control BindingContainer {
186 Control container = NamingContainer;
187 if (container != null && container is INonBindingContainer || (stateMask & BINDING_CONTAINER) == 0)
188 container = container.BindingContainer;
194 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
196 [WebSysDescription ("An Identification of the control that is rendered.")]
197 public virtual string ClientID {
199 string client = UniqueID;
202 client = UniqueID2ClientID (client);
209 internal string UniqueID2ClientID (string uniqueId)
211 return uniqueId.Replace (IdSeparator, ClientIDSeparator);
214 protected char ClientIDSeparator {
219 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
221 [WebSysDescription ("The child controls of this control.")]
222 public virtual ControlCollection Controls { //DIT
224 if (_controls == null)
225 _controls = CreateControlCollection ();
230 [MonoTODO ("revisit once we have a real design strategy")]
231 protected internal bool DesignMode {
232 get { return false; }
235 [DefaultValue (true), WebCategory ("Behavior")]
236 [WebSysDescription ("An Identification of the control that is rendered.")]
238 public virtual bool EnableViewState {
239 get { return ((stateMask & ENABLE_VIEWSTATE) != 0); }
240 set { SetMask (ENABLE_VIEWSTATE, value); }
243 [MergableProperty (false), ParenthesizePropertyName (true)]
244 [WebSysDescription ("The name of the control that is rendered.")]
245 [Filterable (false), Themeable (false)]
246 public virtual string ID {
247 get { return (((stateMask & ID_SET) != 0) ? _userId : null); }
250 if (value != null && value.Length == 0)
259 protected internal bool IsChildControlStateCleared {
260 get { return _isChildControlStateCleared; }
263 protected bool LoadViewStateByID {
265 if (loadViewStateByID == null)
266 loadViewStateByID = IsLoadViewStateByID ();
268 return (bool)loadViewStateByID;
272 protected internal bool IsViewStateEnabled {
274 for (Control control = this; control != null; control = control.Parent)
275 if (!control.EnableViewState)
282 protected char IdSeparator {
286 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
288 [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]
289 public virtual Control NamingContainer {
291 if (_namingContainer == null && _parent != null) {
292 if ((_parent.stateMask & IS_NAMING_CONTAINER) == 0)
293 _namingContainer = _parent.NamingContainer;
295 _namingContainer = _parent;
298 return _namingContainer;
302 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
304 [WebSysDescription ("The webpage that this control resides on.")]
306 public virtual Page Page { //DIT
309 if (NamingContainer != null)
310 _page = NamingContainer.Page;
311 else if (Parent != null)
317 set { _page = value; }
320 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
322 [WebSysDescription ("The parent control of this control.")]
323 public virtual Control Parent { //DIT
324 get { return _parent; }
327 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
328 [EditorBrowsable (EditorBrowsableState.Advanced), Browsable (false)]
329 [WebSysDescription ("The site this control is part of.")]
330 public ISite Site { //DIT
331 get { return _site; }
332 set { _site = value; }
336 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
337 public TemplateControl TemplateControl {
338 get { return TemplateControlInternal; }
340 [EditorBrowsable (EditorBrowsableState.Never)]
341 set { _templateControl = value; }
344 internal virtual TemplateControl TemplateControlInternal {
346 if (_templateControl != null)
347 return _templateControl;
349 return _parent.TemplateControl;
355 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
357 [WebSysDescription ("A virtual directory containing the parent of the control.")]
358 public virtual string TemplateSourceDirectory {
360 if (_templateSourceDirectory == null) {
361 TemplateControl tc = TemplateControl;
364 HttpContext ctx = Context;
366 _templateSourceDirectory = VirtualPathUtility.GetDirectory (ctx.Request.CurrentExecutionFilePath);
367 } else if (tc != this)
368 _templateSourceDirectory = tc.TemplateSourceDirectory;
370 if (_templateSourceDirectory == null && this is TemplateControl) {
371 string path = ((TemplateControl) this).AppRelativeVirtualPath;
374 string ret = VirtualPathUtility.GetDirectory (VirtualPathUtility.ToAbsolute (path));
375 int len = ret.Length;
378 if (ret [--len] == '/')
379 _templateSourceDirectory = ret.Substring (0, len);
381 _templateSourceDirectory = String.Empty;
383 if (_templateSourceDirectory == null)
384 _templateSourceDirectory = String.Empty;
387 return _templateSourceDirectory;
392 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
394 [WebSysDescription ("The unique ID of the control.")]
395 public virtual string UniqueID {
397 if (uniqueID != null)
400 if (NamingContainer == null)
405 string prefix = NamingContainer.UniqueID;
406 if (NamingContainer == Page || prefix == null) {
409 if (getFacesContext () != null)
410 uniqueID = getFacesContext ().getExternalContext ().encodeNamespace (uniqueID);
415 uniqueID = prefix + IdSeparator + _userId;
420 void SetMask (int m, bool val) {
427 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
428 [WebSysDescription ("Visiblity state of the control.")]
429 public virtual bool Visible {
431 if ((stateMask & VISIBLE) == 0)
435 return _parent.Visible;
441 if ((value && (stateMask & VISIBLE) == 0) ||
442 (!value && (stateMask & VISIBLE) != 0)) {
443 if (IsTrackingViewState)
444 stateMask |= VISIBLE_CHANGED;
447 SetMask (VISIBLE, value);
451 protected bool ChildControlsCreated {
452 get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
454 if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
455 ControlCollection cc = Controls;
460 SetMask (CHILD_CONTROLS_CREATED, value);
465 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
466 protected internal virtual HttpContext Context { //DIT
472 return HttpContext.Current;
476 protected EventHandlerList Events {
479 _events = new EventHandlerList ();
484 protected bool HasChildViewState {
485 get { return (pendingVS != null && pendingVS.Count > 0); }
488 protected bool IsTrackingViewState {
489 get { return ((stateMask & TRACK_VIEWSTATE) != 0); }
493 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
494 [WebSysDescription ("ViewState")]
495 protected virtual StateBag ViewState {
497 if (_viewState == null)
498 _viewState = new StateBag (ViewStateIgnoresCase);
500 if (IsTrackingViewState)
501 _viewState.TrackViewState ();
508 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
509 protected virtual bool ViewStateIgnoresCase {
510 get { return false; }
513 internal bool AutoEventWireup {
514 get { return (stateMask & AUTO_EVENT_WIREUP) != 0; }
515 set { SetMask (AUTO_EVENT_WIREUP, value); }
518 internal void SetBindingContainer (bool isBC)
520 SetMask (BINDING_CONTAINER, isBC);
523 internal void ResetChildNames ()
525 ResetChildNames (-1);
528 internal void ResetChildNames (int value)
533 defaultNumberID = value;
536 internal int GetDefaultNumberID ()
538 return defaultNumberID;
541 string GetDefaultName ()
544 if (defaultNumberID > 99)
545 defaultName = "ctl" + defaultNumberID++;
547 defaultName = defaultNameArray [defaultNumberID++];
551 void NullifyUniqueID ()
557 for (int i = 0; i < _controls.Count; i++)
558 _controls [i].NullifyUniqueID ();
561 bool IsLoadViewStateByID ()
563 if (loadViewStateByIDCache == null)
564 loadViewStateByIDCache = new Dictionary <Type, bool> ();
567 Type myType = GetType ();
568 if (loadViewStateByIDCache.TryGetValue (myType, out ret))
571 System.ComponentModel.AttributeCollection attrs = TypeDescriptor.GetAttributes (myType);
572 if (attrs != null || attrs.Count > 0) {
574 foreach (Attribute attr in attrs) {
575 if (attr is ViewStateModeByIdAttribute) {
583 loadViewStateByIDCache.Add (myType, ret);
587 protected internal virtual void AddedControl (Control control, int index)
589 ResetControlsCache ();
591 /* Ensure the control don't have more than 1 parent */
592 if (control._parent != null)
593 control._parent.Controls.Remove (control);
595 control._parent = this;
596 Control nc = ((stateMask & IS_NAMING_CONTAINER) != 0) ? this : NamingContainer;
598 if ((stateMask & (INITING | INITED)) != 0) {
599 control.InitRecursive (nc);
600 control.SetMask (REMOVED, false);
602 control.SetNamingContainer (nc);
603 control.SetMask (REMOVED, false);
607 if ((stateMask & (VIEWSTATE_LOADED | LOADED)) != 0) {
608 if (pendingVS != null) {
610 bool byId = LoadViewStateByID;
619 vs = pendingVS [index];
624 pendingVS.Remove (id);
626 pendingVS.Remove (index);
628 if (pendingVS.Count == 0)
631 control.LoadViewStateRecursive (vs);
636 if ((stateMask & LOADED) != 0)
637 control.LoadRecursive ();
639 if ((stateMask & PRERENDERED) != 0)
640 control.PreRenderRecursiveInternal ();
643 void SetNamingContainer (Control nc)
646 _namingContainer = nc;
652 protected virtual void AddParsedSubObject (object obj) //DIT
654 Control c = obj as Control;
659 [EditorBrowsable (EditorBrowsableState.Advanced)]
660 public virtual void ApplyStyleSheetSkin (Page page)
665 if (!EnableTheming) /* this enough? */
668 /* apply the style sheet skin here */
669 if (page.StyleSheetPageTheme != null) {
670 ControlSkin cs = page.StyleSheetPageTheme.GetControlSkin (GetType (), SkinID);
677 protected void BuildProfileTree (string parentId, bool calcViewState)
681 protected void ClearChildControlState ()
683 _isChildControlStateCleared = true;
686 protected void ClearChildState ()
688 ClearChildViewState ();
689 ClearChildControlState ();
692 protected void ClearChildViewState ()
697 protected internal virtual void CreateChildControls () //DIT
701 protected virtual ControlCollection CreateControlCollection () //DIT
703 return new ControlCollection (this);
706 protected virtual void EnsureChildControls ()
708 if (ChildControlsCreated == false && (stateMask & CREATING_CONTROLS) == 0) {
709 stateMask |= CREATING_CONTROLS;
711 Adapter.CreateChildControls ();
713 CreateChildControls ();
714 ChildControlsCreated = true;
715 stateMask &= ~CREATING_CONTROLS;
719 void EnsureIDInternal ()
724 _userId = NamingContainer.GetDefaultName ();
725 SetMask (AUTOID_SET, true);
728 protected void EnsureID ()
730 if (NamingContainer == null)
733 SetMask (ID_SET, true);
736 protected bool HasEvents ()
738 return _events != null;
741 void ResetControlsCache ()
743 _controlsCache = null;
745 if ((this.stateMask & IS_NAMING_CONTAINER) == 0 && Parent != null)
746 Parent.ResetControlsCache ();
749 Hashtable InitControlsCache ()
751 if (_controlsCache != null)
752 return _controlsCache;
754 if ((this.stateMask & IS_NAMING_CONTAINER) != 0 || Parent == null)
755 //LAMESPEC: MS' docs don't mention it, but FindControl is case insensitive.
756 _controlsCache = new Hashtable (StringComparer.OrdinalIgnoreCase);
758 _controlsCache = Parent.InitControlsCache ();
760 return _controlsCache;
763 void EnsureControlsCache ()
765 if (_controlsCache != null)
768 InitControlsCache ();
770 FillControlCache (_controls);
773 void FillControlCache (ControlCollection controls)
775 if (controls == null || controls.Count == 0)
778 foreach (Control c in controls) {
780 if (c._userId != null)
781 _controlsCache.Add (c._userId, c);
782 } catch (ArgumentException) {
783 throw new HttpException (
784 "Multiple controls with the same ID '" +
786 "' were found. FindControl requires that controls have unique IDs. ");
789 if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ())
790 FillControlCache (c.Controls);
794 protected bool IsLiteralContent ()
796 if (_controls != null && _controls.Count == 1 && _controls [0] is LiteralControl)
802 [WebSysDescription ("")]
803 public virtual Control FindControl (string id)
805 return FindControl (id, 0);
808 Control LookForControlByName (string id)
810 EnsureControlsCache ();
811 return (Control) _controlsCache [id];
814 protected virtual Control FindControl (string id, int pathOffset)
816 EnsureChildControls ();
817 Control namingContainer = null;
818 if ((stateMask & IS_NAMING_CONTAINER) == 0) {
819 namingContainer = NamingContainer;
820 if (namingContainer == null)
823 return namingContainer.FindControl (id, pathOffset);
829 int separatorIdx = id.IndexOf (IdSeparator, pathOffset);
830 if (separatorIdx == -1)
831 return LookForControlByName (id.Substring (pathOffset));
833 string idfound = id.Substring (pathOffset, separatorIdx - pathOffset);
834 namingContainer = LookForControlByName (idfound);
835 if (namingContainer == null)
838 return namingContainer.FindControl (id, separatorIdx + 1);
841 protected virtual void LoadViewState (object savedState)
843 if (savedState != null) {
844 ViewState.LoadViewState (savedState);
845 object o = ViewState ["Visible"];
847 SetMask (VISIBLE, (bool) o);
848 stateMask |= VISIBLE_CHANGED;
853 // [MonoTODO("Secure?")]
854 protected string MapPathSecure (string virtualPath)
856 string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
857 return Context.Request.MapPath (combined);
860 protected virtual bool OnBubbleEvent (object source, EventArgs args) //DIT
863 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
864 string type_name = null;
866 type_name = GetType ().Name;
867 trace.Write ("control", String.Concat ("OnBubbleEvent ", _userId, " ", type_name));
873 protected virtual void OnDataBinding (EventArgs e)
875 if ((event_mask & databinding_mask) != 0) {
876 EventHandler eh = (EventHandler) (_events [DataBindingEvent]);
879 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
880 string type_name = null;
882 type_name = GetType ().Name;
883 trace.Write ("control", String.Concat ("OnDataBinding ", _userId, " ", type_name));
891 protected internal virtual void OnInit (EventArgs e)
893 if ((event_mask & init_mask) != 0) {
894 EventHandler eh = (EventHandler) (_events [InitEvent]);
897 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
898 string type_name = null;
900 type_name = GetType ().Name;
901 trace.Write ("control", String.Concat ("OnInit ", _userId, " ", type_name));
909 protected internal virtual void OnLoad (EventArgs e)
911 if ((event_mask & load_mask) != 0) {
912 EventHandler eh = (EventHandler) (_events [LoadEvent]);
915 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
916 string type_name = null;
918 type_name = GetType ().Name;
919 trace.Write ("control", String.Concat ("OnLoad ", _userId, " ", type_name));
927 protected internal virtual void OnPreRender (EventArgs e)
929 if ((event_mask & prerender_mask) != 0) {
930 EventHandler eh = (EventHandler) (_events [PreRenderEvent]);
933 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
934 string type_name = null;
936 type_name = GetType ().Name;
937 trace.Write ("control", String.Concat ("OnPreRender ", _userId, " ", type_name));
945 protected internal virtual void OnUnload (EventArgs e)
947 if ((event_mask & unload_mask) != 0) {
948 EventHandler eh = (EventHandler) (_events [UnloadEvent]);
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.Concat ("OnUnload ", _userId, " ", type_name));
963 protected internal Stream OpenFile (string path)
966 string filePath = Context.Server.MapPath (path);
967 return File.OpenRead (filePath);
969 catch (UnauthorizedAccessException) {
970 throw new HttpException ("Access to the specified file was denied.");
974 internal string GetPhysicalFilePath (string virtualPath)
978 if (VirtualPathUtility.IsAbsolute (virtualPath))
979 return page != null ? page.MapPath (virtualPath) : Context.Server.MapPath (virtualPath);
981 // We need to determine whether one of our parents is a
982 // master page. If so, we need to map the path
983 // relatively to the master page and not our containing
984 // page/control. This is necessary for cases when a
985 // relative path is used in a control placed in a master
986 // page and the master page is referenced from a
987 // location other than its own. In such cases MS.NET looks
988 // for the file in the directory where the master page
991 // An example of where it is needed is at
993 // http://quickstarts.asp.net/QuickStartv20/aspnet/samples/masterpages/masterpages_cs/pages/default.aspx
995 MasterPage master = null;
996 Control ctrl = Parent;
998 while (ctrl != null) {
999 if (ctrl is MasterPage) {
1000 master = ctrl as MasterPage;
1008 path = VirtualPathUtility.Combine (master.TemplateSourceDirectory + "/", virtualPath);
1010 path = VirtualPathUtility.Combine (TemplateSourceDirectory + "/", virtualPath);
1012 return page != null ? page.MapPath (path) : Context.Server.MapPath (path);
1015 protected void RaiseBubbleEvent (object source, EventArgs args)
1020 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1021 string type_name = null;
1022 if (trace != null) {
1023 type_name = GetType ().Name;
1024 trace.Write ("control", String.Concat ("RaiseBubbleEvent ", _userId, " ", type_name));
1027 if (c.OnBubbleEvent (source, args)) {
1030 trace.Write ("control", String.Concat ("End RaiseBubbleEvent (false) ", _userId, " ", type_name));
1036 trace.Write ("control", String.Concat ("End RaiseBubbleEvent (true) ", _userId, " ", type_name));
1042 protected internal virtual void Render (HtmlTextWriter writer) //DIT
1044 RenderChildren (writer);
1047 protected internal virtual void RenderChildren (HtmlTextWriter writer) //DIT
1049 if (_renderMethodDelegate != null) {
1050 _renderMethodDelegate (writer, this);
1054 if (_controls == null)
1057 int len = _controls.Count;
1059 for (int i = 0; i < len; i++) {
1063 ControlAdapter tmp = c.Adapter;
1065 c.RenderControl (writer, tmp);
1067 c.RenderControl (writer);
1071 protected virtual ControlAdapter ResolveAdapter ()
1073 HttpContext context = Context;
1075 if (context == null)
1078 if (!context.Request.BrowserMightHaveAdapters)
1081 // Search up the type hierarchy until we find a control with an adapter.
1082 IDictionary typeMap = context.Request.Browser.Adapters;
1083 Type controlType = GetType ();
1084 Type adapterType = (Type)typeMap [controlType];
1085 while (adapterType == null && controlType != typeof (Control)) {
1086 controlType = controlType.BaseType;
1087 adapterType = (Type)typeMap [controlType];
1090 ControlAdapter a = null;
1091 if (adapterType != null)
1092 a = (ControlAdapter)Activator.CreateInstance (adapterType);
1096 protected virtual object SaveViewState ()
1098 if ((stateMask & VISIBLE_CHANGED) != 0) {
1099 ViewState ["Visible"] = (stateMask & VISIBLE) != 0;
1100 } else if (_viewState == null) {
1104 return _viewState.SaveViewState ();
1107 protected virtual void TrackViewState ()
1109 if (_viewState != null)
1110 _viewState.TrackViewState ();
1112 stateMask |= TRACK_VIEWSTATE;
1115 public virtual void Dispose ()
1117 if ((event_mask & disposed_mask) != 0) {
1118 EventHandler eh = (EventHandler) (_events [DisposedEvent]);
1120 eh (this, EventArgs.Empty);
1124 [WebCategory ("FIXME")]
1125 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]
1126 public event EventHandler DataBinding {
1128 event_mask |= databinding_mask;
1129 Events.AddHandler (DataBindingEvent, value);
1131 remove { Events.RemoveHandler (DataBindingEvent, value); }
1134 [WebSysDescription ("Raised when the contol is disposed.")]
1135 public event EventHandler Disposed {
1137 event_mask |= disposed_mask;
1138 Events.AddHandler (DisposedEvent, value);
1140 remove { Events.RemoveHandler (DisposedEvent, value); }
1143 [WebSysDescription ("Raised when the page containing the control is initialized.")]
1144 public event EventHandler Init {
1146 event_mask |= init_mask;
1147 Events.AddHandler (InitEvent, value);
1149 remove { Events.RemoveHandler (InitEvent, value); }
1152 [WebSysDescription ("Raised after the page containing the control has been loaded.")]
1153 public event EventHandler Load {
1155 event_mask |= load_mask;
1156 Events.AddHandler (LoadEvent, value);
1158 remove { Events.RemoveHandler (LoadEvent, value); }
1161 [WebSysDescription ("Raised before the page containing the control is rendered.")]
1162 public event EventHandler PreRender {
1164 event_mask |= prerender_mask;
1165 Events.AddHandler (PreRenderEvent, value);
1167 remove { Events.RemoveHandler (PreRenderEvent, value); }
1170 [WebSysDescription ("Raised when the page containing the control is unloaded.")]
1171 public event EventHandler Unload {
1173 event_mask |= unload_mask;
1174 Events.AddHandler (UnloadEvent, value);
1176 remove { Events.RemoveHandler (UnloadEvent, value); }
1179 public virtual void DataBind () //DIT
1184 protected virtual void DataBindChildren ()
1186 if (!HasControls ())
1189 int len = _controls != null ? _controls.Count : 0;
1190 for (int i = 0; i < len; i++) {
1191 Control c = _controls [i];
1196 public virtual bool HasControls ()
1198 return (_controls != null && _controls.Count > 0);
1201 public virtual void RenderControl (HtmlTextWriter writer)
1203 if (this.adapter != null) {
1204 RenderControl (writer, this.adapter);
1208 if ((stateMask & VISIBLE) != 0) {
1209 HttpContext ctx = Context;
1210 TraceContext trace = (ctx != null) ? ctx.Trace : null;
1212 if ((trace != null) && trace.IsEnabled)
1213 pos = ctx.Response.GetOutputByteCount ();
1216 if ((trace != null) && trace.IsEnabled) {
1217 int size = ctx.Response.GetOutputByteCount () - pos;
1218 trace.SaveSize (this, size >= 0 ? size : 0);
1223 protected void RenderControl (HtmlTextWriter writer, ControlAdapter adapter)
1225 if ((stateMask & VISIBLE) != 0) {
1226 adapter.BeginRender (writer);
1227 adapter.Render (writer);
1228 adapter.EndRender (writer);
1232 public string ResolveUrl (string relativeUrl)
1234 if (relativeUrl == null)
1235 throw new ArgumentNullException ("relativeUrl");
1237 if (relativeUrl == String.Empty)
1240 if (VirtualPathUtility.IsAbsolute (relativeUrl))
1243 if (relativeUrl [0] == '#')
1246 string ts = AppRelativeTemplateSourceDirectory;
1247 HttpContext ctx = Context;
1248 HttpResponse resp = ctx != null ? ctx.Response : null;
1249 if (ts == null || ts.Length == 0 || resp == null || relativeUrl.IndexOf (':') >= 0)
1252 if (!VirtualPathUtility.IsAppRelative (relativeUrl))
1253 relativeUrl = VirtualPathUtility.Combine (VirtualPathUtility.AppendTrailingSlash (ts), relativeUrl);
1255 return resp.ApplyAppPathModifier (relativeUrl);
1259 public string ResolveClientUrl (string relativeUrl)
1261 if (relativeUrl == null)
1262 throw new ArgumentNullException ("relativeUrl");
1264 if (relativeUrl.Length == 0)
1265 return String.Empty;
1268 relativeUrl = ResolveClientUrlInternal (relativeUrl);
1270 javax.faces.context.FacesContext faces = getFacesContext ();
1275 if (relativeUrl.IndexOf (':') >= 0)
1276 url = ResolveAppRelativeFromFullPath (relativeUrl);
1277 else if (VirtualPathUtility.IsAbsolute (relativeUrl))
1278 url = VirtualPathUtility.ToAppRelative (relativeUrl);
1280 return faces.getApplication ().getViewHandler ().getResourceURL (faces, relativeUrl);
1282 if (VirtualPathUtility.IsAppRelative (url)) {
1283 url = url.Substring (1);
1284 url = url.Length == 0 ? "/" : url;
1285 return faces.getApplication ().getViewHandler ().getResourceURL (faces, url);
1290 string ResolveClientUrlInternal (string relativeUrl) {
1291 if (relativeUrl.StartsWith (J2EE.J2EEConsts.ACTION_URL_PREFIX, StringComparison.Ordinal))
1292 return CreateActionUrl (relativeUrl.Substring (J2EE.J2EEConsts.ACTION_URL_PREFIX.Length));
1294 if (relativeUrl.StartsWith (J2EE.J2EEConsts.RENDER_URL_PREFIX, StringComparison.Ordinal))
1295 return ResolveClientUrl (relativeUrl.Substring (J2EE.J2EEConsts.RENDER_URL_PREFIX.Length));
1298 if (VirtualPathUtility.IsAbsolute (relativeUrl) || relativeUrl.IndexOf (':') >= 0)
1301 HttpContext context = Context;
1302 HttpRequest req = context != null ? context.Request : null;
1304 string templateSourceDirectory = TemplateSourceDirectory;
1305 if (templateSourceDirectory == null || templateSourceDirectory.Length == 0)
1308 string basePath = req.ClientFilePath;
1310 if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/')
1311 basePath = VirtualPathUtility.GetDirectory (basePath, false);
1313 if (VirtualPathUtility.IsAppRelative (relativeUrl))
1314 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1316 string templatePath = VirtualPathUtility.AppendTrailingSlash (templateSourceDirectory);
1318 if (basePath.Length == templatePath.Length && String.CompareOrdinal (basePath, templatePath) == 0)
1321 relativeUrl = VirtualPathUtility.Combine (templatePath, relativeUrl);
1322 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1327 internal bool HasRenderMethodDelegate ()
1329 return _renderMethodDelegate != null;
1332 [EditorBrowsable (EditorBrowsableState.Advanced)]
1333 public void SetRenderMethodDelegate (RenderMethod renderMethod) //DIT
1335 _renderMethodDelegate = renderMethod;
1338 internal void LoadRecursive ()
1341 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1342 string type_name = null;
1343 if (trace != null) {
1344 type_name = GetType ().Name;
1345 trace.Write ("control", String.Concat ("LoadRecursive ", _userId, " ", type_name));
1348 if (Adapter != null)
1349 Adapter.OnLoad (EventArgs.Empty);
1351 OnLoad (EventArgs.Empty);
1352 int ccount = _controls != null ? _controls.Count : 0;
1353 for (int i = 0; i < ccount; i++) {
1354 Control c = _controls [i];
1360 trace.Write ("control", String.Concat ("End LoadRecursive ", _userId, " ", type_name));
1362 stateMask |= LOADED;
1365 internal void UnloadRecursive (Boolean dispose)
1368 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1369 string type_name = null;
1370 if (trace != null) {
1371 type_name = GetType ().Name;
1372 trace.Write ("control", String.Concat ("UnloadRecursive ", _userId, " ", type_name));
1375 int ccount = _controls != null ? _controls.Count : 0;
1376 for (int i = 0; i < ccount; i++) {
1377 Control c = _controls [i];
1378 c.UnloadRecursive (dispose);
1383 trace.Write ("control", String.Concat ("End UnloadRecursive ", _userId, " ", type_name));
1385 ControlAdapter tmp = Adapter;
1387 tmp.OnUnload (EventArgs.Empty);
1389 OnUnload (EventArgs.Empty);
1394 internal void PreRenderRecursiveInternal ()
1400 SetMask (VISIBLE, true);
1401 EnsureChildControls ();
1403 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1404 string type_name = null;
1405 if (trace != null) {
1406 type_name = GetType ().Name;
1407 trace.Write ("control", String.Concat ("PreRenderRecursive ", _userId, " ", type_name));
1410 if (Adapter != null)
1411 Adapter.OnPreRender (EventArgs.Empty);
1413 OnPreRender (EventArgs.Empty);
1414 if (!HasControls ())
1417 int len = _controls != null ? _controls.Count : 0;
1418 for (int i = 0; i < len; i++) {
1419 Control c = _controls [i];
1420 c.PreRenderRecursiveInternal ();
1424 trace.Write ("control", String.Concat ("End PreRenderRecursive ", _userId, " ", type_name));
1427 SetMask (VISIBLE, false);
1429 stateMask |= PRERENDERED;
1432 internal void InitRecursive (Control namingContainer)
1435 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1436 string type_name = null;
1437 if (trace != null) {
1438 type_name = GetType ().Name;
1439 trace.Write ("control", String.Concat ("InitRecursive ", _userId, " ", type_name));
1442 SetNamingContainer (namingContainer);
1444 if (HasControls ()) {
1445 if ((stateMask & IS_NAMING_CONTAINER) != 0)
1446 namingContainer = this;
1448 int len = _controls != null ? _controls.Count : 0;
1449 for (int i = 0; i < len; i++) {
1450 Control c = _controls [i];
1451 c.InitRecursive (namingContainer);
1455 if ((stateMask & REMOVED) == 0 && (stateMask & INITED) != INITED) {
1456 stateMask |= INITING;
1458 ControlAdapter tmp = Adapter;
1460 tmp.OnInit (EventArgs.Empty);
1462 OnInit (EventArgs.Empty);
1464 stateMask |= INITED;
1465 stateMask &= ~INITING;
1470 trace.Write ("control", String.Concat ("End InitRecursive ", _userId, " ", type_name));
1474 internal object SaveViewStateRecursive ()
1476 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1478 string type_name = null;
1479 if (trace != null) {
1480 type_name = GetType ().Name;
1481 trace.Write ("control", String.Concat ("SaveViewStateRecursive ", _userId, " ", type_name));
1485 ArrayList controlStates = null;
1486 bool byId = LoadViewStateByID;
1487 if (HasControls ()) {
1488 int len = _controls != null ? _controls.Count : 0;
1489 for (int i = 0; i < len; i++) {
1490 Control ctrl = _controls [i];
1491 object ctrlState = ctrl.SaveViewStateRecursive ();
1492 if (ctrlState == null)
1495 if (controlStates == null)
1496 controlStates = new ArrayList ();
1499 controlStates.Add (new Pair (ctrl.ID, ctrlState));
1501 controlStates.Add (new Pair (i, ctrlState));
1505 object thisAdapterViewState = null;
1506 if (Adapter != null)
1507 thisAdapterViewState = Adapter.SaveAdapterViewState ();
1509 object thisState = null;
1511 if (IsViewStateEnabled)
1512 thisState = SaveViewState ();
1514 if (thisState == null && controlStates == null) {
1515 if (trace != null) {
1517 trace.Write ("control", "End SaveViewStateRecursive " + _userId + " " + type_name + " saved nothing");
1519 trace.SaveViewState (this, null);
1524 if (trace != null) {
1526 trace.Write ("control", "End SaveViewStateRecursive " + _userId + " " + type_name + " saved a Triplet");
1528 trace.SaveViewState (this, thisState);
1530 thisState = new object[] { thisState, thisAdapterViewState };
1531 return new Pair (thisState, controlStates);
1534 internal void LoadViewStateRecursive (object savedState)
1536 if (savedState == null)
1540 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1541 string type_name = null;
1542 if (trace != null) {
1543 type_name = GetType ().Name;
1544 trace.Write ("control", String.Concat ("LoadViewStateRecursive ", _userId, " ", type_name));
1547 Pair savedInfo = (Pair) savedState;
1548 object[] controlAndAdapterViewStates = (object [])savedInfo.First;
1549 if (Adapter != null)
1550 Adapter.LoadAdapterViewState (controlAndAdapterViewStates [1]);
1551 LoadViewState (controlAndAdapterViewStates [0]);
1553 ArrayList controlStates = savedInfo.Second as ArrayList;
1554 if (controlStates == null)
1557 int nControls = controlStates.Count;
1558 bool byId = LoadViewStateByID;
1559 for (int i = 0; i < nControls; i++) {
1560 Pair p = controlStates [i] as Pair;
1565 string id = (string)p.First;
1568 foreach (Control c in Controls) {
1572 c.LoadViewStateRecursive (p.Second);
1578 if (pendingVS == null)
1579 pendingVS = new Hashtable ();
1580 pendingVS [id] = p.Second;
1583 int k = (int) p.First;
1584 if (k < Controls.Count) {
1585 Control c = Controls [k];
1586 c.LoadViewStateRecursive (p.Second);
1588 if (pendingVS == null)
1589 pendingVS = new Hashtable ();
1591 pendingVS [k] = p.Second;
1598 trace.Write ("control", String.Concat ("End LoadViewStateRecursive ", _userId, " ", type_name));
1600 stateMask |= VIEWSTATE_LOADED;
1603 internal ControlSkin controlSkin;
1605 internal void ApplyTheme ()
1608 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1609 string type_name = null;
1610 if (trace != null) {
1611 type_name = GetType ().Name;
1612 trace.Write ("control", String.Concat ("ApplyThemeRecursive ", _userId, " ", type_name));
1616 if (page != null && page.PageTheme != null && EnableTheming) {
1617 ControlSkin controlSkin = page.PageTheme.GetControlSkin (GetType (), SkinID);
1618 if (controlSkin != null)
1619 controlSkin.ApplySkin (this);
1624 trace.Write ("control", String.Concat ("End ApplyThemeRecursive ", _userId, " ", type_name));
1628 internal bool AutoID {
1629 get { return (stateMask & AUTOID) != 0; }
1631 if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
1634 SetMask (AUTOID, value);
1638 protected internal virtual void RemovedControl (Control control)
1640 control.UnloadRecursive (false);
1641 control._parent = null;
1642 control._page = null;
1643 control._namingContainer = null;
1644 if ((control.stateMask & AUTOID_SET) != 0) {
1645 control._userId = null;
1646 control.SetMask (ID_SET, false);
1648 control.NullifyUniqueID ();
1649 control.SetMask (REMOVED, true);
1650 ResetControlsCache ();
1653 string skinId = string.Empty;
1654 bool _enableTheming = true;
1658 [DefaultValue (true)]
1659 public virtual bool EnableTheming {
1661 if ((stateMask & ENABLE_THEMING) != 0)
1662 return _enableTheming;
1664 if (_parent != null)
1665 return _parent.EnableTheming;
1670 SetMask (ENABLE_THEMING, true);
1671 _enableTheming = value;
1677 [Filterable (false)]
1678 public virtual string SkinID {
1679 get { return skinId; }
1680 set { skinId = value; }
1683 ControlBuilder IControlBuilderAccessor.ControlBuilder {
1684 get { throw new NotImplementedException (); }
1687 IDictionary IControlDesignerAccessor.GetDesignModeState ()
1689 throw new NotImplementedException ();
1692 void IControlDesignerAccessor.SetDesignModeState (IDictionary designData)
1694 SetDesignModeState (designData);
1697 void IControlDesignerAccessor.SetOwnerControl (Control control)
1699 throw new NotImplementedException ();
1702 IDictionary IControlDesignerAccessor.UserData {
1703 get { throw new NotImplementedException (); }
1706 ExpressionBindingCollection expressionBindings;
1708 ExpressionBindingCollection IExpressionsAccessor.Expressions {
1710 if (expressionBindings == null)
1711 expressionBindings = new ExpressionBindingCollection ();
1712 return expressionBindings;
1716 bool IExpressionsAccessor.HasExpressions {
1717 get { return (expressionBindings != null && expressionBindings.Count > 0); }
1720 public virtual void Focus ()
1722 Page.SetFocus (this);
1725 protected internal virtual void LoadControlState (object state)
1729 protected internal virtual object SaveControlState ()
1734 protected virtual void DataBind (bool raiseOnDataBinding)
1736 bool foundDataItem = false;
1738 if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
1739 object o = DataBinder.GetDataItem (this, out foundDataItem);
1741 Page.PushDataItemContext (o);
1745 if (raiseOnDataBinding)
1746 OnDataBinding (EventArgs.Empty);
1747 DataBindChildren ();
1750 Page.PopDataItemContext ();
1754 protected virtual IDictionary GetDesignModeState ()
1756 throw new NotImplementedException ();
1759 protected virtual void SetDesignModeState (IDictionary data)
1761 throw new NotImplementedException ();
1764 internal bool IsInited {
1765 get { return (stateMask & INITED) != 0; }
1768 internal bool IsLoaded {
1769 get { return (stateMask & LOADED) != 0; }
1772 internal bool IsPrerendered {
1773 get { return (stateMask & PRERENDERED) != 0; }
1776 bool CheckForValidationSupport ()
1778 return GetType ().GetCustomAttributes (typeof (SupportsEventValidationAttribute), false).Length > 0;
1782 // Apparently this is where .NET routes validation from all the controls which
1785 // http://odetocode.com/Blogs/scott/archive/2006/03/20/3145.aspx
1786 // Sample in here contains ValidateEvent in the stack trace
1788 // http://odetocode.com/blogs/scott/archive/2006/03/21/3153.aspx
1790 // http://www.alexthissen.nl/blogs/main/archive/2005/12/13/event-validation-of-controls-in-asp-net-2-0.aspx
1792 // It also seems that it's the control's responsibility to call this method or
1793 // validation won't take place. Also, the SupportsEventValidation attribute must be
1794 // present on the control for validation to take place.
1796 internal void ValidateEvent (String uniqueId, String argument)
1800 if (page != null && CheckForValidationSupport ())
1801 page.ClientScript.ValidateEvent (uniqueId, argument);
1804 void IParserAccessor.AddParsedSubObject (object obj)
1806 this.AddParsedSubObject (obj);
1809 DataBindingCollection IDataBindingsAccessor.DataBindings {
1811 if (dataBindings == null) {
1812 dataBindings = new DataBindingCollection ();
1814 return dataBindings;
1818 bool IDataBindingsAccessor.HasDataBindings {
1820 if (dataBindings != null && dataBindings.Count > 0) {