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;
134 const int REMOVED = 1 << 18;
139 defaultNameArray = new string [100];
140 for (int i = 0; i < 100; i++)
142 defaultNameArray [i] = String.Concat ("ctl", i.ToString ("D2"));
144 defaultNameArray [i] = "_ctl" + i;
150 stateMask = ENABLE_VIEWSTATE | VISIBLE | AUTOID | BINDING_CONTAINER | AUTO_EVENT_WIREUP;
151 if (this is INamingContainer)
152 stateMask |= IS_NAMING_CONTAINER;
156 ControlAdapter adapter;
157 bool did_adapter_lookup;
158 protected internal ControlAdapter Adapter {
160 if (!did_adapter_lookup) {
161 adapter = ResolveAdapter ();
163 adapter.Control = this;
164 did_adapter_lookup = true;
170 string _appRelativeTemplateSourceDirectory = null;
172 [EditorBrowsable (EditorBrowsableState.Advanced)]
174 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
175 public string AppRelativeTemplateSourceDirectory {
177 if (_appRelativeTemplateSourceDirectory != null)
178 return _appRelativeTemplateSourceDirectory;
180 string tempSrcDir = null;
181 TemplateControl templateControl = TemplateControl;
182 if (templateControl != null) {
183 string templateVirtualPath = templateControl.AppRelativeVirtualPath;
184 if (!String.IsNullOrEmpty (templateVirtualPath))
185 tempSrcDir = VirtualPathUtility.GetDirectory (templateVirtualPath, false);
188 _appRelativeTemplateSourceDirectory = (tempSrcDir != null) ? tempSrcDir : VirtualPathUtility.ToAppRelative (TemplateSourceDirectory);
189 return _appRelativeTemplateSourceDirectory;
191 [EditorBrowsable (EditorBrowsableState.Never)]
193 _appRelativeTemplateSourceDirectory = value;
194 _templateSourceDirectory = null;
200 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
201 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
202 public Control BindingContainer {
204 Control container = NamingContainer;
205 if (container != null && container is INonBindingContainer || (stateMask & BINDING_CONTAINER) == 0)
206 container = container.BindingContainer;
212 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
214 [WebSysDescription ("An Identification of the control that is rendered.")]
215 public virtual string ClientID {
217 string client = UniqueID;
221 client = UniqueID2ClientID (client);
223 client = client.Replace (':', ClientIDSeparator);
232 internal string UniqueID2ClientID (string uniqueId)
234 return uniqueId.Replace (IdSeparator, ClientIDSeparator);
237 protected char ClientIDSeparator
239 char ClientIDSeparator
246 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
248 [WebSysDescription ("The child controls of this control.")]
249 public virtual ControlCollection Controls { //DIT
251 if (_controls == null)
252 _controls = CreateControlCollection ();
258 [MonoTODO ("revisit once we have a real design strategy")]
259 protected internal bool DesignMode {
260 get { return false; }
264 [DefaultValue (true), WebCategory ("Behavior")]
265 [WebSysDescription ("An Identification of the control that is rendered.")]
269 public virtual bool EnableViewState {
270 get { return ((stateMask & ENABLE_VIEWSTATE) != 0); }
271 set { SetMask (ENABLE_VIEWSTATE, value); }
274 [MergableProperty (false), ParenthesizePropertyName (true)]
275 [WebSysDescription ("The name of the control that is rendered.")]
277 [Filterable (false), Themeable (false)]
280 public virtual string ID {
281 get { return (((stateMask & ID_SET) != 0) ? _userId : null); }
294 protected internal bool IsChildControlStateCleared {
295 get { return _isChildControlStateCleared; }
298 protected bool LoadViewStateByID {
299 get { return false; }
306 bool IsViewStateEnabled {
308 for (Control control = this; control != null; control = control.Parent)
309 if (!control.EnableViewState)
317 protected char IdSeparator {
321 internal char IdSeparator {
326 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
328 [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]
329 public virtual Control NamingContainer {
331 if (_namingContainer == null && _parent != null) {
332 if ((_parent.stateMask & IS_NAMING_CONTAINER) == 0)
333 _namingContainer = _parent.NamingContainer;
335 _namingContainer = _parent;
338 return _namingContainer;
342 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
344 [WebSysDescription ("The webpage that this control resides on.")]
348 public virtual Page Page { //DIT
351 if (NamingContainer != null)
352 _page = NamingContainer.Page;
353 else if (Parent != null)
359 set { _page = value; }
362 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
364 [WebSysDescription ("The parent control of this control.")]
365 public virtual Control Parent { //DIT
366 get { return _parent; }
369 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
370 [EditorBrowsable (EditorBrowsableState.Advanced), Browsable (false)]
371 [WebSysDescription ("The site this control is part of.")]
372 public ISite Site { //DIT
373 get { return _site; }
374 set { _site = value; }
379 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
380 public TemplateControl TemplateControl {
381 get { return TemplateControlInternal; }
383 [EditorBrowsable (EditorBrowsableState.Never)]
384 set { _templateControl = value; }
387 internal virtual TemplateControl TemplateControlInternal {
389 if (_templateControl != null)
390 return _templateControl;
392 return _parent.TemplateControl;
399 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
401 [WebSysDescription ("A virtual directory containing the parent of the control.")]
402 public virtual string TemplateSourceDirectory {
405 if (_templateSourceDirectory == null) {
406 TemplateControl tc = TemplateControl;
409 HttpContext ctx = Context;
411 _templateSourceDirectory = VirtualPathUtility.GetDirectory (ctx.Request.CurrentExecutionFilePath);
412 } else if (tc != this)
413 _templateSourceDirectory = tc.TemplateSourceDirectory;
415 if (_templateSourceDirectory == null && this is TemplateControl) {
416 string path = ((TemplateControl) this).AppRelativeVirtualPath;
419 string ret = VirtualPathUtility.GetDirectory (VirtualPathUtility.ToAbsolute (path));
420 int len = ret.Length;
423 if (ret [--len] == '/')
424 _templateSourceDirectory = ret.Substring (0, len);
426 _templateSourceDirectory = String.Empty;
428 if (_templateSourceDirectory == null)
429 _templateSourceDirectory = String.Empty;
432 return _templateSourceDirectory;
434 if (_templateSourceDirectory == null) {
435 HttpContext ctx = HttpContext.Current;
436 HttpRequest req = ctx != null ? ctx.Request : null;
438 _templateSourceDirectory = (_parent == null)
439 ? req != null ? VirtualPathUtility.RemoveTrailingSlash (
440 VirtualPathUtility.GetDirectory (
441 HttpContext.Current.Request.CurrentExecutionFilePath)) : String.Empty
442 : _parent.TemplateSourceDirectory;
444 return _templateSourceDirectory;
450 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
452 [WebSysDescription ("The unique ID of the control.")]
453 public virtual string UniqueID {
455 if (uniqueID != null)
458 if (NamingContainer == null)
463 string prefix = NamingContainer.UniqueID;
464 if (NamingContainer == Page || prefix == null) {
467 if (getFacesContext () != null)
468 uniqueID = getFacesContext ().getExternalContext ().encodeNamespace (uniqueID);
473 uniqueID = prefix + IdSeparator + _userId;
478 void SetMask (int m, bool val) {
485 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
486 [WebSysDescription ("Visiblity state of the control.")]
487 public virtual bool Visible {
489 if ((stateMask & VISIBLE) == 0)
493 return _parent.Visible;
499 if ((value && (stateMask & VISIBLE) == 0) ||
500 (!value && (stateMask & VISIBLE) != 0)) {
501 if (IsTrackingViewState)
502 stateMask |= VISIBLE_CHANGED;
505 SetMask (VISIBLE, value);
509 protected bool ChildControlsCreated {
510 get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
512 if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
513 if (_controls != null)
517 SetMask (CHILD_CONTROLS_CREATED, value);
522 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
528 virtual HttpContext Context { //DIT
536 return HttpContext.Current;
537 HttpContext context = _parent.Context;
542 return HttpContext.Current;
546 protected EventHandlerList Events {
549 _events = new EventHandlerList ();
554 protected bool HasChildViewState {
555 get { return (pendingVS != null && pendingVS.Count > 0); }
558 protected bool IsTrackingViewState {
559 get { return ((stateMask & TRACK_VIEWSTATE) != 0); }
563 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
564 [WebSysDescription ("ViewState")]
565 protected virtual StateBag ViewState {
567 if (_viewState == null)
568 _viewState = new StateBag (ViewStateIgnoresCase);
570 if (IsTrackingViewState)
571 _viewState.TrackViewState ();
578 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
579 protected virtual bool ViewStateIgnoresCase {
580 get { return false; }
583 internal bool AutoEventWireup {
584 get { return (stateMask & AUTO_EVENT_WIREUP) != 0; }
585 set { SetMask (AUTO_EVENT_WIREUP, value); }
588 internal void SetBindingContainer (bool isBC)
590 SetMask (BINDING_CONTAINER, isBC);
593 internal void ResetChildNames ()
595 ResetChildNames (-1);
598 internal void ResetChildNames (int value)
603 defaultNumberID = value;
606 internal int GetDefaultNumberID ()
608 return defaultNumberID;
611 string GetDefaultName ()
614 if (defaultNumberID > 99) {
616 defaultName = "ctl" + defaultNumberID++;
618 defaultName = "_ctl" + defaultNumberID++;
621 defaultName = defaultNameArray [defaultNumberID++];
626 void NullifyUniqueID ()
632 for (int i = 0; i < _controls.Count; i++)
633 _controls [i].NullifyUniqueID ();
636 protected internal virtual void AddedControl (Control control, int index)
638 ResetControlsCache ();
640 /* Ensure the control don't have more than 1 parent */
641 if (control._parent != null)
642 control._parent.Controls.Remove (control);
644 control._parent = this;
645 Control nc = ((stateMask & IS_NAMING_CONTAINER) != 0) ? this : NamingContainer;
647 if ((stateMask & (INITING | INITED)) != 0) {
648 control.InitRecursive (nc);
649 control.SetMask (REMOVED, false);
651 control.SetNamingContainer (nc);
652 control.SetMask (REMOVED, false);
656 if ((stateMask & (VIEWSTATE_LOADED | LOADED)) != 0) {
657 if (pendingVS != null) {
658 object vs = pendingVS [index];
660 pendingVS.Remove (index);
661 if (pendingVS.Count == 0)
664 control.LoadViewStateRecursive (vs);
669 if ((stateMask & LOADED) != 0)
670 control.LoadRecursive ();
672 if ((stateMask & PRERENDERED) != 0)
673 control.PreRenderRecursiveInternal ();
676 void SetNamingContainer (Control nc)
679 _namingContainer = nc;
685 protected virtual void AddParsedSubObject (object obj) //DIT
687 Control c = obj as Control;
693 [EditorBrowsable (EditorBrowsableState.Advanced)]
694 public virtual void ApplyStyleSheetSkin (Page page)
696 if (!EnableTheming) /* this enough? */
699 /* apply the style sheet skin here */
700 if (page.StyleSheetPageTheme != null) {
701 ControlSkin cs = page.StyleSheetPageTheme.GetControlSkin (GetType (), SkinID);
708 protected void BuildProfileTree (string parentId, bool calcViewState)
714 protected void ClearChildControlState ()
716 _isChildControlStateCleared = true;
719 protected void ClearChildState ()
721 ClearChildViewState ();
722 ClearChildControlState ();
726 protected void ClearChildViewState ()
736 virtual void CreateChildControls () //DIT
740 protected virtual ControlCollection CreateControlCollection () //DIT
742 return new ControlCollection (this);
745 protected virtual void EnsureChildControls ()
747 if (ChildControlsCreated == false && (stateMask & CREATING_CONTROLS) == 0) {
748 stateMask |= CREATING_CONTROLS;
751 Adapter.CreateChildControls ();
754 CreateChildControls ();
755 ChildControlsCreated = true;
756 stateMask &= ~CREATING_CONTROLS;
760 void EnsureIDInternal ()
765 _userId = NamingContainer.GetDefaultName ();
766 SetMask (AUTOID_SET, true);
770 protected void EnsureID ()
772 if (NamingContainer == null)
775 SetMask (ID_SET, true);
778 protected bool HasEvents ()
780 return _events != null;
784 void ResetControlsCache ()
786 _controlsCache = null;
788 if ((this.stateMask & IS_NAMING_CONTAINER) == 0 && Parent != null)
789 Parent.ResetControlsCache ();
792 Hashtable InitControlsCache ()
794 if (_controlsCache != null)
795 return _controlsCache;
797 if ((this.stateMask & IS_NAMING_CONTAINER) != 0 || Parent == null)
798 //LAMESPEC: MS' docs don't mention it, but FindControl is case insensitive.
800 _controlsCache = new Hashtable (StringComparer.OrdinalIgnoreCase);
802 _controlsCache = new Hashtable (CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);
805 _controlsCache = Parent.InitControlsCache ();
807 return _controlsCache;
810 void EnsureControlsCache ()
812 if (_controlsCache != null)
815 InitControlsCache ();
816 FillControlCache (Controls);
820 void FillControlCache (ControlCollection controls)
822 foreach (Control c in controls) {
824 if (c._userId != null)
825 _controlsCache.Add (c._userId, c);
826 } catch (ArgumentException) {
827 throw new HttpException (
828 "Multiple controls with the same ID '" +
830 "' were found. FindControl requires that controls have unique IDs. ");
833 if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ())
834 FillControlCache (c.Controls);
838 protected bool IsLiteralContent ()
840 if (HasControls () && _controls.Count == 1 && (_controls [0] is LiteralControl))
846 [WebSysDescription ("")]
847 public virtual Control FindControl (string id)
849 return FindControl (id, 0);
852 Control LookForControlByName (string id)
854 EnsureControlsCache ();
855 return (Control) _controlsCache [id];
858 protected virtual Control FindControl (string id, int pathOffset)
860 EnsureChildControls ();
861 Control namingContainer = null;
862 if ((stateMask & IS_NAMING_CONTAINER) == 0) {
863 namingContainer = NamingContainer;
864 if (namingContainer == null)
867 return namingContainer.FindControl (id, pathOffset);
873 int separatorIdx = id.IndexOf (IdSeparator, pathOffset);
874 if (separatorIdx == -1)
875 return LookForControlByName (id.Substring (pathOffset));
877 string idfound = id.Substring (pathOffset, separatorIdx - pathOffset);
878 namingContainer = LookForControlByName (idfound);
879 if (namingContainer == null)
882 return namingContainer.FindControl (id, separatorIdx + 1);
885 protected virtual void LoadViewState (object savedState)
887 if (savedState != null) {
888 ViewState.LoadViewState (savedState);
889 object o = ViewState ["Visible"];
891 SetMask (VISIBLE, (bool) o);
892 stateMask |= VISIBLE_CHANGED;
897 // [MonoTODO("Secure?")]
898 protected string MapPathSecure (string virtualPath)
900 string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
901 return Context.Request.MapPath (combined);
904 protected virtual bool OnBubbleEvent (object source, EventArgs args) //DIT
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.Concat ("OnBubbleEvent ", _userId, " ", type_name));
917 protected virtual void OnDataBinding (EventArgs e)
919 if ((event_mask & databinding_mask) != 0) {
920 EventHandler eh = (EventHandler) (_events [DataBindingEvent]);
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 ("OnDataBinding ", _userId, " ", type_name));
940 virtual void OnInit (EventArgs e)
942 if ((event_mask & init_mask) != 0) {
943 EventHandler eh = (EventHandler) (_events [InitEvent]);
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 ("OnInit ", _userId, " ", type_name));
963 virtual void OnLoad (EventArgs e)
965 if ((event_mask & load_mask) != 0) {
966 EventHandler eh = (EventHandler) (_events [LoadEvent]);
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 ("OnLoad ", _userId, " ", type_name));
986 virtual void OnPreRender (EventArgs e)
988 if ((event_mask & prerender_mask) != 0) {
989 EventHandler eh = (EventHandler) (_events [PreRenderEvent]);
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 ("OnPreRender ", _userId, " ", type_name));
1009 virtual void OnUnload (EventArgs e)
1011 if ((event_mask & unload_mask) != 0) {
1012 EventHandler eh = (EventHandler) (_events [UnloadEvent]);
1015 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1016 string type_name = null;
1017 if (trace != null) {
1018 type_name = GetType ().Name;
1019 trace.Write ("control", String.Concat ("OnUnload ", _userId, " ", type_name));
1028 protected internal Stream OpenFile (string path)
1031 string filePath = Context.Server.MapPath (path);
1032 return File.OpenRead (filePath);
1034 catch (UnauthorizedAccessException) {
1035 throw new HttpException ("Access to the specified file was denied.");
1039 internal string GetPhysicalFilePath (string virtualPath)
1043 if (VirtualPathUtility.IsAbsolute (virtualPath))
1044 return page != null ? page.MapPath (virtualPath) : Context.Server.MapPath (virtualPath);
1046 // We need to determine whether one of our parents is a
1047 // master page. If so, we need to map the path
1048 // relatively to the master page and not our containing
1049 // page/control. This is necessary for cases when a
1050 // relative path is used in a control placed in a master
1051 // page and the master page is referenced from a
1052 // location other than its own. In such cases MS.NET looks
1053 // for the file in the directory where the master page
1056 // An example of where it is needed is at
1058 // http://quickstarts.asp.net/QuickStartv20/aspnet/samples/masterpages/masterpages_cs/pages/default.aspx
1060 MasterPage master = null;
1061 Control ctrl = Parent;
1063 while (ctrl != null) {
1064 if (ctrl is MasterPage) {
1065 master = ctrl as MasterPage;
1073 path = VirtualPathUtility.Combine (master.TemplateSourceDirectory + "/", virtualPath);
1075 path = VirtualPathUtility.Combine (TemplateSourceDirectory + "/", virtualPath);
1077 return page != null ? page.MapPath (path) : Context.Server.MapPath (path);
1081 protected void RaiseBubbleEvent (object source, EventArgs args)
1086 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1087 string type_name = null;
1088 if (trace != null) {
1089 type_name = GetType ().Name;
1090 trace.Write ("control", String.Concat ("RaiseBubbleEvent ", _userId, " ", type_name));
1093 if (c.OnBubbleEvent (source, args)) {
1096 trace.Write ("control", String.Concat ("End RaiseBubbleEvent (false) ", _userId, " ", type_name));
1102 trace.Write ("control", String.Concat ("End RaiseBubbleEvent (true) ", _userId, " ", type_name));
1113 virtual void Render (HtmlTextWriter writer) //DIT
1115 RenderChildren (writer);
1123 virtual void RenderChildren (HtmlTextWriter writer) //DIT
1125 if (_renderMethodDelegate != null) {
1126 _renderMethodDelegate (writer, this);
1127 } else if (_controls != null) {
1128 int len = _controls.Count;
1130 for (int i = 0; i < len; i++) {
1135 ControlAdapter tmp = c.Adapter;
1137 c.RenderControl (writer, tmp);
1140 c.RenderControl (writer);
1146 protected virtual ControlAdapter ResolveAdapter ()
1148 HttpContext context = Context;
1150 if (context == null)
1153 if (!context.Request.BrowserMightHaveAdapters)
1156 // Search up the type hierarchy until we find a control with an adapter.
1157 IDictionary typeMap = context.Request.Browser.Adapters;
1158 Type controlType = GetType ();
1159 Type adapterType = (Type)typeMap [controlType];
1160 while (adapterType == null && controlType != typeof (Control)) {
1161 controlType = controlType.BaseType;
1162 adapterType = (Type)typeMap [controlType];
1165 ControlAdapter a = null;
1166 if (adapterType != null)
1167 a = (ControlAdapter)Activator.CreateInstance (adapterType);
1172 protected virtual object SaveViewState ()
1174 if ((stateMask & VISIBLE_CHANGED) != 0) {
1175 ViewState ["Visible"] = (stateMask & VISIBLE) != 0;
1176 } else if (_viewState == null) {
1180 return _viewState.SaveViewState ();
1183 protected virtual void TrackViewState ()
1185 if (_viewState != null)
1186 _viewState.TrackViewState ();
1188 stateMask |= TRACK_VIEWSTATE;
1191 public virtual void Dispose ()
1193 if ((event_mask & disposed_mask) != 0) {
1194 EventHandler eh = (EventHandler) (_events [DisposedEvent]);
1196 eh (this, EventArgs.Empty);
1200 [WebCategory ("FIXME")]
1201 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]
1202 public event EventHandler DataBinding {
1204 event_mask |= databinding_mask;
1205 Events.AddHandler (DataBindingEvent, value);
1207 remove { Events.RemoveHandler (DataBindingEvent, value); }
1210 [WebSysDescription ("Raised when the contol is disposed.")]
1211 public event EventHandler Disposed {
1213 event_mask |= disposed_mask;
1214 Events.AddHandler (DisposedEvent, value);
1216 remove { Events.RemoveHandler (DisposedEvent, value); }
1219 [WebSysDescription ("Raised when the page containing the control is initialized.")]
1220 public event EventHandler Init {
1222 event_mask |= init_mask;
1223 Events.AddHandler (InitEvent, value);
1225 remove { Events.RemoveHandler (InitEvent, value); }
1228 [WebSysDescription ("Raised after the page containing the control has been loaded.")]
1229 public event EventHandler Load {
1231 event_mask |= load_mask;
1232 Events.AddHandler (LoadEvent, value);
1234 remove { Events.RemoveHandler (LoadEvent, value); }
1237 [WebSysDescription ("Raised before the page containing the control is rendered.")]
1238 public event EventHandler PreRender {
1240 event_mask |= prerender_mask;
1241 Events.AddHandler (PreRenderEvent, value);
1243 remove { Events.RemoveHandler (PreRenderEvent, value); }
1246 [WebSysDescription ("Raised when the page containing the control is unloaded.")]
1247 public event EventHandler Unload {
1249 event_mask |= unload_mask;
1250 Events.AddHandler (UnloadEvent, value);
1252 remove { Events.RemoveHandler (UnloadEvent, value); }
1255 public virtual void DataBind () //DIT
1260 OnDataBinding (EventArgs.Empty);
1269 void DataBindChildren ()
1271 if (!HasControls ())
1274 int len = _controls.Count;
1275 for (int i = 0; i < len; i++) {
1276 Control c = _controls [i];
1281 public virtual bool HasControls ()
1283 return (_controls != null && _controls.Count > 0);
1291 void RenderControl (HtmlTextWriter writer)
1294 if (this.adapter != null) {
1295 RenderControl (writer, this.adapter);
1300 if ((stateMask & VISIBLE) != 0) {
1301 HttpContext ctx = Context;
1302 TraceContext trace = (ctx != null) ? ctx.Trace : null;
1304 if ((trace != null) && trace.IsEnabled)
1305 pos = ctx.Response.GetOutputByteCount ();
1308 if ((trace != null) && trace.IsEnabled) {
1309 int size = ctx.Response.GetOutputByteCount () - pos;
1310 trace.SaveSize (this, size >= 0 ? size : 0);
1316 protected void RenderControl (HtmlTextWriter writer, ControlAdapter adapter)
1318 if ((stateMask & VISIBLE) != 0) {
1319 adapter.BeginRender (writer);
1320 adapter.Render (writer);
1321 adapter.EndRender (writer);
1326 public string ResolveUrl (string relativeUrl)
1328 if (relativeUrl == null)
1329 throw new ArgumentNullException ("relativeUrl");
1331 if (relativeUrl == String.Empty)
1334 if (VirtualPathUtility.IsAbsolute (relativeUrl))
1337 if (relativeUrl [0] == '#')
1341 string ts = AppRelativeTemplateSourceDirectory;
1343 string ts = TemplateSourceDirectory;
1346 HttpContext ctx = Context;
1347 HttpResponse resp = ctx != null ? ctx.Response : null;
1348 if (ts == null || ts.Length == 0 || resp == null || relativeUrl.IndexOf (':') >= 0)
1351 if (!VirtualPathUtility.IsAppRelative (relativeUrl))
1352 relativeUrl = VirtualPathUtility.Combine (VirtualPathUtility.AppendTrailingSlash (ts), relativeUrl);
1354 return resp.ApplyAppPathModifier (relativeUrl);
1363 string ResolveClientUrl (string relativeUrl)
1365 if (relativeUrl == null)
1366 throw new ArgumentNullException ("relativeUrl");
1368 if (relativeUrl.Length == 0)
1369 return String.Empty;
1372 relativeUrl = ResolveClientUrlInternal (relativeUrl);
1374 javax.faces.context.FacesContext faces = getFacesContext ();
1379 if (relativeUrl.IndexOf (':') >= 0)
1380 url = ResolveAppRelativeFromFullPath (relativeUrl);
1381 else if (VirtualPathUtility.IsAbsolute (relativeUrl))
1382 url = VirtualPathUtility.ToAppRelative (relativeUrl);
1384 return faces.getApplication ().getViewHandler ().getResourceURL (faces, relativeUrl);
1386 if (VirtualPathUtility.IsAppRelative (url)) {
1387 url = url.Substring (1);
1388 url = url.Length == 0 ? "/" : url;
1389 return faces.getApplication ().getViewHandler ().getResourceURL (faces, url);
1394 string ResolveClientUrlInternal (string relativeUrl) {
1395 if (relativeUrl.StartsWith (J2EE.J2EEConsts.ACTION_URL_PREFIX, StringComparison.Ordinal))
1396 return CreateActionUrl (relativeUrl.Substring (J2EE.J2EEConsts.ACTION_URL_PREFIX.Length));
1398 if (relativeUrl.StartsWith (J2EE.J2EEConsts.RENDER_URL_PREFIX, StringComparison.Ordinal))
1399 return ResolveClientUrl (relativeUrl.Substring (J2EE.J2EEConsts.RENDER_URL_PREFIX.Length));
1402 if (VirtualPathUtility.IsAbsolute (relativeUrl) || relativeUrl.IndexOf (':') >= 0)
1405 HttpContext context = Context;
1406 if (context != null && context.Request != null) {
1407 string templateSourceDirectory = TemplateSourceDirectory;
1408 if (templateSourceDirectory == null || templateSourceDirectory.Length == 0)
1411 string basePath = context.Request.FilePath;
1413 if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/')
1414 basePath = VirtualPathUtility.GetDirectory (basePath, false);
1416 if (VirtualPathUtility.IsAppRelative (relativeUrl))
1417 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1419 string templatePath = VirtualPathUtility.AppendTrailingSlash (templateSourceDirectory);
1421 if (basePath.Length == templatePath.Length && String.CompareOrdinal (basePath, templatePath) == 0)
1424 relativeUrl = VirtualPathUtility.Combine (templatePath, relativeUrl);
1425 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1430 internal bool HasRenderMethodDelegate ()
1432 return _renderMethodDelegate != null;
1435 [EditorBrowsable (EditorBrowsableState.Advanced)]
1436 public void SetRenderMethodDelegate (RenderMethod renderMethod) //DIT
1438 _renderMethodDelegate = renderMethod;
1441 internal void LoadRecursive ()
1444 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1445 string type_name = null;
1446 if (trace != null) {
1447 type_name = GetType ().Name;
1448 trace.Write ("control", String.Concat ("LoadRecursive ", _userId, " ", type_name));
1452 if (Adapter != null)
1453 Adapter.OnLoad (EventArgs.Empty);
1456 OnLoad (EventArgs.Empty);
1457 if (HasControls ()) {
1458 int len = _controls.Count;
1459 for (int i = 0; i < len; i++) {
1460 Control c = _controls [i];
1467 trace.Write ("control", String.Concat ("End LoadRecursive ", _userId, " ", type_name));
1469 stateMask |= LOADED;
1472 internal void UnloadRecursive (Boolean dispose)
1475 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1476 string type_name = null;
1477 if (trace != null) {
1478 type_name = GetType ().Name;
1479 trace.Write ("control", String.Concat ("UnloadRecursive ", _userId, " ", type_name));
1482 if (HasControls ()) {
1483 int len = _controls.Count;
1484 for (int i = 0; i < len; i++) {
1485 Control c = _controls [i];
1486 c.UnloadRecursive (dispose);
1492 trace.Write ("control", String.Concat ("End UnloadRecursive ", _userId, " ", type_name));
1495 ControlAdapter tmp = Adapter;
1497 tmp.OnUnload (EventArgs.Empty);
1500 OnUnload (EventArgs.Empty);
1505 internal void PreRenderRecursiveInternal ()
1512 visible = (stateMask & VISIBLE) != 0;
1517 SetMask (VISIBLE, true);
1519 EnsureChildControls ();
1521 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1522 string type_name = null;
1523 if (trace != null) {
1524 type_name = GetType ().Name;
1525 trace.Write ("control", String.Concat ("PreRenderRecursive ", _userId, " ", type_name));
1529 if (Adapter != null)
1530 Adapter.OnPreRender (EventArgs.Empty);
1533 OnPreRender (EventArgs.Empty);
1534 if (!HasControls ())
1537 int len = _controls.Count;
1538 for (int i = 0; i < len; i++) {
1539 Control c = _controls [i];
1540 c.PreRenderRecursiveInternal ();
1544 trace.Write ("control", String.Concat ("End PreRenderRecursive ", _userId, " ", type_name));
1549 SetMask (VISIBLE, false);
1552 stateMask |= PRERENDERED;
1555 internal void InitRecursive (Control namingContainer)
1558 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1559 string type_name = null;
1560 if (trace != null) {
1561 type_name = GetType ().Name;
1562 trace.Write ("control", String.Concat ("InitRecursive ", _userId, " ", type_name));
1565 SetNamingContainer (namingContainer);
1567 if (HasControls ()) {
1568 if ((stateMask & IS_NAMING_CONTAINER) != 0)
1569 namingContainer = this;
1571 int len = _controls.Count;
1572 for (int i = 0; i < len; i++) {
1573 Control c = _controls [i];
1574 c.InitRecursive (namingContainer);
1578 if ((stateMask & REMOVED) == 0 && (stateMask & INITED) != INITED) {
1579 stateMask |= INITING;
1582 ControlAdapter tmp = Adapter;
1584 tmp.OnInit (EventArgs.Empty);
1587 OnInit (EventArgs.Empty);
1589 stateMask |= INITED;
1590 stateMask &= ~INITING;
1595 trace.Write ("control", String.Concat ("End InitRecursive ", _userId, " ", type_name));
1599 internal object SaveViewStateRecursive ()
1601 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1603 string type_name = null;
1604 if (trace != null) {
1605 type_name = GetType ().Name;
1606 trace.Write ("control", String.Concat ("SaveViewStateRecursive ", _userId, " ", type_name));
1610 ArrayList controlList = null;
1611 ArrayList controlStates = null;
1614 if (HasControls ()) {
1615 int len = _controls.Count;
1616 for (int i = 0; i < len; i++) {
1617 Control ctrl = _controls [i];
1618 object ctrlState = ctrl.SaveViewStateRecursive ();
1620 if (ctrlState == null)
1623 if (controlList == null) {
1624 controlList = new ArrayList ();
1625 controlStates = new ArrayList ();
1628 controlList.Add (idx);
1629 controlStates.Add (ctrlState);
1634 object thisAdapterViewState = null;
1635 if (Adapter != null)
1636 thisAdapterViewState = Adapter.SaveAdapterViewState ();
1638 object thisState = null;
1640 if (IsViewStateEnabled)
1641 thisState = SaveViewState ();
1643 if (thisState == null && controlList == null && controlStates == null) {
1644 if (trace != null) {
1646 trace.Write ("control", "End SaveViewStateRecursive " + _userId + " " + type_name + " saved nothing");
1648 trace.SaveViewState (this, null);
1653 if (trace != null) {
1655 trace.Write ("control", "End SaveViewStateRecursive " + _userId + " " + type_name + " saved a Triplet");
1657 trace.SaveViewState (this, thisState);
1660 thisState = new object[] { thisState, thisAdapterViewState };
1662 return new Triplet (thisState, controlList, controlStates);
1665 internal void LoadViewStateRecursive (object savedState)
1667 if (savedState == null)
1671 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1672 string type_name = null;
1673 if (trace != null) {
1674 type_name = GetType ().Name;
1675 trace.Write ("control", String.Concat ("LoadViewStateRecursive ", _userId, " ", type_name));
1678 Triplet savedInfo = (Triplet) savedState;
1680 object[] controlAndAdapterViewStates = (object [])savedInfo.First;
1681 if (Adapter != null)
1682 Adapter.LoadAdapterViewState (controlAndAdapterViewStates [1]);
1683 LoadViewState (controlAndAdapterViewStates [0]);
1685 LoadViewState (savedInfo.First);
1688 ArrayList controlList = savedInfo.Second as ArrayList;
1689 if (controlList == null)
1691 ArrayList controlStates = savedInfo.Third as ArrayList;
1692 int nControls = controlList.Count;
1693 for (int i = 0; i < nControls; i++) {
1694 int k = (int) controlList [i];
1695 if (k < Controls.Count && controlStates != null) {
1696 Control c = Controls [k];
1697 c.LoadViewStateRecursive (controlStates [i]);
1700 if (pendingVS == null)
1701 pendingVS = new Hashtable ();
1703 pendingVS [k] = controlStates [i];
1709 trace.Write ("control", String.Concat ("End LoadViewStateRecursive ", _userId, " ", type_name));
1711 stateMask |= VIEWSTATE_LOADED;
1715 internal ControlSkin controlSkin;
1717 internal void ApplyTheme ()
1720 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1721 string type_name = null;
1722 if (trace != null) {
1723 type_name = GetType ().Name;
1724 trace.Write ("control", String.Concat ("ApplyThemeRecursive ", _userId, " ", type_name));
1728 if (page != null && page.PageTheme != null && EnableTheming) {
1729 ControlSkin controlSkin = page.PageTheme.GetControlSkin (GetType (), SkinID);
1730 if (controlSkin != null)
1731 controlSkin.ApplySkin (this);
1736 trace.Write ("control", String.Concat ("End ApplyThemeRecursive ", _userId, " ", type_name));
1741 internal bool AutoID {
1742 get { return (stateMask & AUTOID) != 0; }
1744 if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
1747 SetMask (AUTOID, value);
1751 protected internal virtual void RemovedControl (Control control)
1753 control.UnloadRecursive (false);
1754 control._parent = null;
1755 control._page = null;
1756 control._namingContainer = null;
1757 if ((control.stateMask & AUTOID_SET) != 0) {
1758 control._userId = null;
1759 control.SetMask (ID_SET, false);
1761 control.NullifyUniqueID ();
1762 control.SetMask (REMOVED, true);
1763 ResetControlsCache ();
1767 string skinId = string.Empty;
1768 bool _enableTheming = true;
1772 [DefaultValue (true)]
1773 public virtual bool EnableTheming {
1775 if ((stateMask & ENABLE_THEMING) != 0)
1776 return _enableTheming;
1778 if (_parent != null)
1779 return _parent.EnableTheming;
1784 SetMask (ENABLE_THEMING, true);
1785 _enableTheming = value;
1791 [Filterable (false)]
1792 public virtual string SkinID {
1793 get { return skinId; }
1794 set { skinId = value; }
1797 ControlBuilder IControlBuilderAccessor.ControlBuilder {
1798 get { throw new NotImplementedException (); }
1801 IDictionary IControlDesignerAccessor.GetDesignModeState ()
1803 throw new NotImplementedException ();
1806 void IControlDesignerAccessor.SetDesignModeState (IDictionary designData)
1808 SetDesignModeState (designData);
1811 void IControlDesignerAccessor.SetOwnerControl (Control control)
1813 throw new NotImplementedException ();
1816 IDictionary IControlDesignerAccessor.UserData {
1817 get { throw new NotImplementedException (); }
1820 ExpressionBindingCollection expressionBindings;
1822 ExpressionBindingCollection IExpressionsAccessor.Expressions {
1824 if (expressionBindings == null)
1825 expressionBindings = new ExpressionBindingCollection ();
1826 return expressionBindings;
1830 bool IExpressionsAccessor.HasExpressions {
1831 get { return (expressionBindings != null && expressionBindings.Count > 0); }
1834 public virtual void Focus ()
1836 Page.SetFocus (this);
1839 protected internal virtual void LoadControlState (object state)
1843 protected internal virtual object SaveControlState ()
1848 protected virtual void DataBind (bool raiseOnDataBinding)
1850 bool foundDataItem = false;
1852 if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
1853 object o = DataBinder.GetDataItem (this, out foundDataItem);
1855 Page.PushDataItemContext (o);
1859 if (raiseOnDataBinding)
1860 OnDataBinding (EventArgs.Empty);
1861 DataBindChildren ();
1864 Page.PopDataItemContext ();
1868 protected virtual IDictionary GetDesignModeState ()
1870 throw new NotImplementedException ();
1873 protected virtual void SetDesignModeState (IDictionary data)
1875 throw new NotImplementedException ();
1878 internal bool IsInited {
1879 get { return (stateMask & INITED) != 0; }
1882 internal bool IsLoaded {
1883 get { return (stateMask & LOADED) != 0; }
1886 internal bool IsPrerendered {
1887 get { return (stateMask & PRERENDERED) != 0; }
1890 bool CheckForValidationSupport ()
1892 return GetType ().GetCustomAttributes (typeof (SupportsEventValidationAttribute), false).Length > 0;
1896 // Apparently this is where .NET routes validation from all the controls which
1899 // http://odetocode.com/Blogs/scott/archive/2006/03/20/3145.aspx
1900 // Sample in here contains ValidateEvent in the stack trace
1902 // http://odetocode.com/blogs/scott/archive/2006/03/21/3153.aspx
1904 // http://www.alexthissen.nl/blogs/main/archive/2005/12/13/event-validation-of-controls-in-asp-net-2-0.aspx
1906 // It also seems that it's the control's responsibility to call this method or
1907 // validation won't take place. Also, the SupportsEventValidation attribute must be
1908 // present on the control for validation to take place.
1910 internal void ValidateEvent (String uniqueId, String argument)
1914 if (page != null && CheckForValidationSupport ())
1915 page.ClientScript.ValidateEvent (uniqueId, argument);
1918 void IParserAccessor.AddParsedSubObject (object obj)
1920 this.AddParsedSubObject (obj);
1923 DataBindingCollection IDataBindingsAccessor.DataBindings {
1925 if (dataBindings == null) {
1926 dataBindings = new DataBindingCollection ();
1928 return dataBindings;
1932 bool IDataBindingsAccessor.HasDataBindings {
1934 if (dataBindings != null && dataBindings.Count > 0) {