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 static readonly object DataBindingEvent = new object ();
73 static readonly object DisposedEvent = new object ();
74 static readonly object InitEvent = new object ();
75 static readonly object LoadEvent = new object ();
76 static readonly object PreRenderEvent = new object ();
77 static readonly object UnloadEvent = new object ();
78 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;
98 EventHandlerList _events;
99 RenderMethod _renderMethodDelegate;
100 Hashtable _controlsCache;
103 DataBindingCollection dataBindings;
104 Hashtable pendingVS; // may hold unused viewstate data from child controls
108 TemplateControl _templateControl;
109 bool _isChildControlStateCleared;
111 string _templateSourceDirectory;
115 const int ENABLE_VIEWSTATE = 1;
116 const int VISIBLE = 1 << 1;
117 const int AUTOID = 1 << 2;
118 const int CREATING_CONTROLS = 1 << 3;
119 const int BINDING_CONTAINER = 1 << 4;
120 const int AUTO_EVENT_WIREUP = 1 << 5;
121 const int IS_NAMING_CONTAINER = 1 << 6;
122 const int VISIBLE_CHANGED = 1 << 7;
123 const int TRACK_VIEWSTATE = 1 << 8;
124 const int CHILD_CONTROLS_CREATED = 1 << 9;
125 const int ID_SET = 1 << 10;
126 const int INITED = 1 << 11;
127 const int INITING = 1 << 12;
128 const int VIEWSTATE_LOADED = 1 << 13;
129 const int LOADED = 1 << 14;
130 const int PRERENDERED = 1 << 15;
132 const int ENABLE_THEMING = 1 << 16;
134 const int AUTOID_SET = 1 << 17;
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 [MonoTODO ("Not implemented, always returns null")]
157 protected ControlAdapter Adapter {
159 // for the time being, fool the
160 // Control machinery into thinking we
161 // don't have an Adapter. This will
162 // allow us to write all the rest of
163 // the Adapter handling code without
164 // having to worry about *having*
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;
182 TemplateControl templateControl = TemplateControl;
183 if (templateControl != null)
184 if (!string.IsNullOrEmpty (templateControl.AppRelativeVirtualPath))
185 tempSrcDir = VirtualPathUtility.GetDirectory (templateControl.AppRelativeVirtualPath, false);
187 _appRelativeTemplateSourceDirectory = (tempSrcDir != null) ? tempSrcDir : "~/";
188 return _appRelativeTemplateSourceDirectory;
190 [EditorBrowsable (EditorBrowsableState.Never)]
192 _appRelativeTemplateSourceDirectory = value;
193 _templateSourceDirectory = null;
199 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
200 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
201 public Control BindingContainer {
203 Control container = NamingContainer;
204 if (container != null && (container.stateMask & BINDING_CONTAINER) == 0)
205 container = container.BindingContainer;
210 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
212 [WebSysDescription ("An Identification of the control that is rendered.")]
213 public virtual string ClientID {
215 string client = UniqueID;
219 client = UniqueID2ClientID (client);
221 client = client.Replace (':', ClientIDSeparator);
230 internal string UniqueID2ClientID (string uniqueId)
232 return uniqueId.Replace (IdSeparator, ClientIDSeparator);
235 protected char ClientIDSeparator
237 char ClientIDSeparator
244 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
246 [WebSysDescription ("The child controls of this control.")]
247 public virtual ControlCollection Controls { //DIT
249 if (_controls == null)
250 _controls = CreateControlCollection ();
256 [MonoTODO ("revisit once we have a real design strategy")]
257 protected internal bool DesignMode {
258 get { return false; }
262 [DefaultValue (true), WebCategory ("Behavior")]
263 [WebSysDescription ("An Identification of the control that is rendered.")]
267 public virtual bool EnableViewState {
268 get { return ((stateMask & ENABLE_VIEWSTATE) != 0); }
269 set { SetMask (ENABLE_VIEWSTATE, value); }
272 [MergableProperty (false), ParenthesizePropertyName (true)]
273 [WebSysDescription ("The name of the control that is rendered.")]
275 [Filterable (false), Themeable (false)]
278 public virtual string ID {
279 get { return (((stateMask & ID_SET) != 0) ? _userId : null); }
292 protected char IdSeparator {
296 protected internal bool IsChildControlStateCleared {
297 get { return _isChildControlStateCleared; }
300 protected internal bool IsViewStateEnabled {
302 for (Control control = this; control != null; control = control.Parent)
303 if (!control.EnableViewState)
310 protected bool LoadViewStateByID {
311 get { return false; }
315 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
317 [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]
318 public virtual Control NamingContainer {
320 if (_namingContainer == null && _parent != null) {
321 if ((_parent.stateMask & IS_NAMING_CONTAINER) == 0)
322 _namingContainer = _parent.NamingContainer;
324 _namingContainer = _parent;
327 return _namingContainer;
331 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
333 [WebSysDescription ("The webpage that this control resides on.")]
337 public virtual Page Page { //DIT
340 if (NamingContainer != null)
341 _page = NamingContainer.Page;
342 else if (Parent != null)
348 set { _page = value; }
351 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
353 [WebSysDescription ("The parent control of this control.")]
354 public virtual Control Parent { //DIT
355 get { return _parent; }
358 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
359 [EditorBrowsable (EditorBrowsableState.Advanced), Browsable (false)]
360 [WebSysDescription ("The site this control is part of.")]
361 public ISite Site { //DIT
362 get { return _site; }
363 set { _site = value; }
368 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
369 public TemplateControl TemplateControl {
370 get { return TemplateControlInternal; }
372 [EditorBrowsable (EditorBrowsableState.Never)]
373 set { _templateControl = value; }
376 internal virtual TemplateControl TemplateControlInternal {
378 if (_templateControl != null)
379 return _templateControl;
381 return _parent.TemplateControl;
388 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
390 [WebSysDescription ("A virtual directory containing the parent of the control.")]
391 public virtual string TemplateSourceDirectory {
394 if (_templateSourceDirectory == null) {
395 TemplateControl tc = TemplateControl;
398 HttpContext ctx = Context;
400 _templateSourceDirectory = VirtualPathUtility.GetDirectory (ctx.Request.CurrentExecutionFilePath);
401 } else if (tc != this)
402 _templateSourceDirectory = tc.TemplateSourceDirectory;
404 if (_templateSourceDirectory == null && this is TemplateControl) {
405 string path = ((TemplateControl) this).AppRelativeVirtualPath;
408 // Pretend our application virtual root is "/" even if it isn't - we just
409 // want to get an absolute url out of relative one, without the real
410 // application root prepended to it.
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;
457 // For J2EE portlets we need to add the namespace to the ID.
458 if (NamingContainer == Page && Page.PortletNamespace != null)
459 prefix = Page.PortletNamespace;
462 if (NamingContainer == Page || prefix == null) {
468 uniqueID = prefix + IdSeparator + _userId;
470 uniqueID = prefix + ":" + _userId;
476 void SetMask (int m, bool val) {
483 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
484 [WebSysDescription ("Visiblity state of the control.")]
485 public virtual bool Visible {
487 if ((stateMask & VISIBLE) == 0)
491 return _parent.Visible;
497 if ((value && (stateMask & VISIBLE) == 0) ||
498 (!value && (stateMask & VISIBLE) != 0)) {
499 if (IsTrackingViewState)
500 stateMask |= VISIBLE_CHANGED;
503 SetMask (VISIBLE, value);
507 protected bool ChildControlsCreated {
508 get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
510 if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
511 if (_controls != null)
515 SetMask (CHILD_CONTROLS_CREATED, value);
520 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
521 protected virtual HttpContext Context { //DIT
524 if (_context != null)
527 return HttpContext.Current;
528 context = _parent.Context;
531 return HttpContext.Current;
535 protected EventHandlerList Events {
538 _events = new EventHandlerList ();
543 protected bool HasChildViewState {
544 get { return (pendingVS != null && pendingVS.Count > 0); }
547 protected bool IsTrackingViewState {
548 get { return ((stateMask & TRACK_VIEWSTATE) != 0); }
552 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
553 [WebSysDescription ("ViewState")]
554 protected virtual StateBag ViewState {
556 if (_viewState == null)
557 _viewState = new StateBag (ViewStateIgnoresCase);
559 if (IsTrackingViewState)
560 _viewState.TrackViewState ();
567 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
568 protected virtual bool ViewStateIgnoresCase {
569 get { return false; }
572 internal bool AutoEventWireup {
573 get { return (stateMask & AUTO_EVENT_WIREUP) != 0; }
574 set { SetMask (AUTO_EVENT_WIREUP, value); }
577 internal void SetBindingContainer (bool isBC)
579 SetMask (BINDING_CONTAINER, isBC);
582 internal void ResetChildNames ()
587 string GetDefaultName ()
590 if (defaultNumberID > 99) {
592 defaultName = "ctl" + defaultNumberID++;
594 defaultName = "_ctl" + defaultNumberID++;
597 defaultName = defaultNameArray [defaultNumberID++];
602 void NullifyUniqueID ()
608 for (int i = 0; i < _controls.Count; i++)
609 _controls [i].NullifyUniqueID ();
612 protected internal virtual void AddedControl (Control control, int index)
614 ResetControlsCache ();
616 /* Ensure the control don't have more than 1 parent */
617 if (control._parent != null)
618 control._parent.Controls.Remove (control);
620 control._parent = this;
621 Control nc = ((stateMask & IS_NAMING_CONTAINER) != 0) ? this : NamingContainer;
623 if ((stateMask & (INITING | INITED)) != 0)
624 control.InitRecursive (nc);
626 control.SetNamingContainer (nc);
630 if ((stateMask & (VIEWSTATE_LOADED | LOADED)) != 0) {
631 if (pendingVS != null) {
632 object vs = pendingVS [index];
634 pendingVS.Remove (index);
635 if (pendingVS.Count == 0)
638 control.LoadViewStateRecursive (vs);
643 if ((stateMask & LOADED) != 0)
644 control.LoadRecursive ();
646 if ((stateMask & PRERENDERED) != 0)
647 control.PreRenderRecursiveInternal ();
650 void SetNamingContainer (Control nc)
653 _namingContainer = nc;
659 protected virtual void AddParsedSubObject (object obj) //DIT
661 Control c = obj as Control;
667 [EditorBrowsable (EditorBrowsableState.Advanced)]
668 public virtual void ApplyStyleSheetSkin (Page page)
670 if (!EnableTheming) /* this enough? */
673 /* apply the style sheet skin here */
674 if (page.StyleSheetPageTheme != null) {
675 ControlSkin cs = page.StyleSheetPageTheme.GetControlSkin (GetType (), SkinID);
682 protected void BuildProfileTree (string parentId, bool calcViewState)
688 protected void ClearChildControlState ()
690 _isChildControlStateCleared = true;
693 protected void ClearChildState ()
695 ClearChildViewState ();
696 ClearChildControlState ();
700 protected void ClearChildViewState ()
710 virtual void CreateChildControls () //DIT
714 protected virtual ControlCollection CreateControlCollection () //DIT
716 return new ControlCollection (this);
719 protected virtual void EnsureChildControls ()
721 if (ChildControlsCreated == false && (stateMask & CREATING_CONTROLS) == 0) {
722 stateMask |= CREATING_CONTROLS;
725 Adapter.CreateChildControls ();
728 CreateChildControls ();
729 ChildControlsCreated = true;
730 stateMask &= ~CREATING_CONTROLS;
734 void EnsureIDInternal ()
739 _userId = NamingContainer.GetDefaultName ();
740 SetMask (AUTOID_SET, true);
744 protected void EnsureID ()
746 if (NamingContainer == null)
749 SetMask (ID_SET, true);
752 protected bool HasEvents ()
754 return _events != null;
758 void ResetControlsCache ()
760 _controlsCache = null;
762 if ((this.stateMask & IS_NAMING_CONTAINER) == 0 && Parent != null)
763 Parent.ResetControlsCache ();
766 Hashtable InitControlsCache ()
768 if (_controlsCache != null)
769 return _controlsCache;
771 if ((this.stateMask & IS_NAMING_CONTAINER) != 0 || Parent == null)
772 //LAMESPEC: MS' docs don't mention it, but FindControl is case insensitive.
774 _controlsCache = new Hashtable (StringComparer.OrdinalIgnoreCase);
776 _controlsCache = new Hashtable (CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);
779 _controlsCache = Parent.InitControlsCache ();
781 return _controlsCache;
784 void EnsureControlsCache ()
786 if (_controlsCache != null)
789 InitControlsCache ();
790 FillControlCache (this);
794 void FillControlCache (Control control)
799 foreach (Control c in control._controls) {
801 if (c._userId != null)
802 _controlsCache.Add (c._userId, c);
803 } catch (Exception ex) {
804 throw new HttpException ("Found more than one control with ID '" + c._userId + "'", ex);
807 if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ())
808 FillControlCache (c);
812 protected bool IsLiteralContent ()
814 if (HasControls () && _controls.Count == 1 && (_controls [0] is LiteralControl))
820 [WebSysDescription ("")]
821 public virtual Control FindControl (string id)
823 return FindControl (id, 0);
826 Control LookForControlByName (string id)
829 if (this == Page && id != null && id == Page.PortletNamespace)
832 EnsureControlsCache ();
833 return (Control) _controlsCache [id];
836 protected virtual Control FindControl (string id, int pathOffset)
838 EnsureChildControls ();
839 Control namingContainer = null;
840 if ((stateMask & IS_NAMING_CONTAINER) == 0) {
841 namingContainer = NamingContainer;
842 if (namingContainer == null)
845 return namingContainer.FindControl (id, pathOffset);
851 int separatorIdx = id.IndexOf (IdSeparator, pathOffset);
853 int separatorIdx = id.IndexOf (':', pathOffset);
855 if (separatorIdx == -1)
856 return LookForControlByName (id.Substring (pathOffset));
858 string idfound = id.Substring (pathOffset, separatorIdx - pathOffset);
859 namingContainer = LookForControlByName (idfound);
860 if (namingContainer == null)
863 return namingContainer.FindControl (id, separatorIdx + 1);
866 protected virtual void LoadViewState (object savedState)
868 if (savedState != null) {
869 ViewState.LoadViewState (savedState);
870 object o = ViewState ["Visible"];
872 SetMask (VISIBLE, (bool) o);
873 stateMask |= VISIBLE_CHANGED;
878 // [MonoTODO("Secure?")]
879 protected string MapPathSecure (string virtualPath)
881 string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
882 return Context.Request.MapPath (combined);
885 protected virtual bool OnBubbleEvent (object source, EventArgs args) //DIT
888 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
889 string type_name = null;
891 type_name = GetType ().Name;
892 trace.Write ("control", String.Concat ("OnBubbleEvent ", _userId, " ", type_name));
898 protected virtual void OnDataBinding (EventArgs e)
900 if ((event_mask & databinding_mask) != 0) {
901 EventHandler eh = (EventHandler) (_events [DataBindingEvent]);
904 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
905 string type_name = null;
907 type_name = GetType ().Name;
908 trace.Write ("control", String.Concat ("OnDataBinding ", _userId, " ", type_name));
921 virtual void OnInit (EventArgs e)
923 if ((event_mask & init_mask) != 0) {
924 EventHandler eh = (EventHandler) (_events [InitEvent]);
927 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
928 string type_name = null;
930 type_name = GetType ().Name;
931 trace.Write ("control", String.Concat ("OnInit ", _userId, " ", type_name));
944 virtual void OnLoad (EventArgs e)
946 if ((event_mask & load_mask) != 0) {
947 EventHandler eh = (EventHandler) (_events [LoadEvent]);
950 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
951 string type_name = null;
953 type_name = GetType ().Name;
954 trace.Write ("control", String.Concat ("OnLoad ", _userId, " ", type_name));
967 virtual void OnPreRender (EventArgs e)
969 if ((event_mask & prerender_mask) != 0) {
970 EventHandler eh = (EventHandler) (_events [PreRenderEvent]);
973 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
974 string type_name = null;
976 type_name = GetType ().Name;
977 trace.Write ("control", String.Concat ("OnPreRender ", _userId, " ", type_name));
990 virtual void OnUnload (EventArgs e)
992 if ((event_mask & unload_mask) != 0) {
993 EventHandler eh = (EventHandler) (_events [UnloadEvent]);
996 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
997 string type_name = null;
999 type_name = GetType ().Name;
1000 trace.Write ("control", String.Concat ("OnUnload ", _userId, " ", type_name));
1009 protected internal Stream OpenFile (string path)
1012 string filePath = Context.Server.MapPath (path);
1013 return File.OpenRead (filePath);
1015 catch (UnauthorizedAccessException) {
1016 throw new HttpException ("Access to the specified file was denied.");
1020 internal string GetPhysicalFilePath (string virtualPath)
1024 if (VirtualPathUtility.IsAbsolute (virtualPath))
1025 return page != null ? page.MapPath (virtualPath) : Context.Server.MapPath (virtualPath);
1027 // We need to determine whether one of our parents is a
1028 // master page. If so, we need to map the path
1029 // relatively to the master page and not our containing
1030 // page/control. This is necessary for cases when a
1031 // relative path is used in a control placed in a master
1032 // page and the master page is referenced from a
1033 // location other than its own. In such cases MS.NET looks
1034 // for the file in the directory where the master page
1037 // An example of where it is needed is at
1039 // http://quickstarts.asp.net/QuickStartv20/aspnet/samples/masterpages/masterpages_cs/pages/default.aspx
1041 MasterPage master = null;
1042 Control ctrl = Parent;
1044 while (ctrl != null) {
1045 if (ctrl is MasterPage) {
1046 master = ctrl as MasterPage;
1054 path = VirtualPathUtility.Combine (master.TemplateSourceDirectory + "/", virtualPath);
1056 path = VirtualPathUtility.Combine (TemplateSourceDirectory + "/", virtualPath);
1058 return page != null ? page.MapPath (path) : Context.Server.MapPath (path);
1062 protected void RaiseBubbleEvent (object source, EventArgs args)
1067 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1068 string type_name = null;
1069 if (trace != null) {
1070 type_name = GetType ().Name;
1071 trace.Write ("control", String.Concat ("RaiseBubbleEvent ", _userId, " ", type_name));
1074 if (c.OnBubbleEvent (source, args)) {
1077 trace.Write ("control", String.Concat ("End RaiseBubbleEvent (false) ", _userId, " ", type_name));
1083 trace.Write ("control", String.Concat ("End RaiseBubbleEvent (true) ", _userId, " ", type_name));
1094 virtual void Render (HtmlTextWriter writer) //DIT
1096 RenderChildren (writer);
1104 virtual void RenderChildren (HtmlTextWriter writer) //DIT
1106 if (_renderMethodDelegate != null) {
1107 _renderMethodDelegate (writer, this);
1108 } else if (_controls != null) {
1109 int len = _controls.Count;
1111 for (int i = 0; i < len; i++) {
1116 if (c.Adapter != null)
1117 c.RenderControl (writer, c.Adapter);
1120 c.RenderControl (writer);
1126 protected virtual ControlAdapter ResolveAdapter ()
1128 throw new NotImplementedException ();
1132 protected virtual object SaveViewState ()
1134 if ((stateMask & VISIBLE_CHANGED) != 0) {
1135 ViewState ["Visible"] = (stateMask & VISIBLE) != 0;
1136 } else if (_viewState == null) {
1140 return _viewState.SaveViewState ();
1143 protected virtual void TrackViewState ()
1145 if (_viewState != null)
1146 _viewState.TrackViewState ();
1148 stateMask |= TRACK_VIEWSTATE;
1151 public virtual void Dispose ()
1153 if ((event_mask & disposed_mask) != 0) {
1154 EventHandler eh = (EventHandler) (_events [DisposedEvent]);
1156 eh (this, EventArgs.Empty);
1160 [WebCategory ("FIXME")]
1161 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]
1162 public event EventHandler DataBinding {
1164 event_mask |= databinding_mask;
1165 Events.AddHandler (DataBindingEvent, value);
1167 remove { Events.RemoveHandler (DataBindingEvent, value); }
1170 [WebSysDescription ("Raised when the contol is disposed.")]
1171 public event EventHandler Disposed {
1173 event_mask |= disposed_mask;
1174 Events.AddHandler (DisposedEvent, value);
1176 remove { Events.RemoveHandler (DisposedEvent, value); }
1179 [WebSysDescription ("Raised when the page containing the control is initialized.")]
1180 public event EventHandler Init {
1182 event_mask |= init_mask;
1183 Events.AddHandler (InitEvent, value);
1185 remove { Events.RemoveHandler (InitEvent, value); }
1188 [WebSysDescription ("Raised after the page containing the control has been loaded.")]
1189 public event EventHandler Load {
1191 event_mask |= load_mask;
1192 Events.AddHandler (LoadEvent, value);
1194 remove { Events.RemoveHandler (LoadEvent, value); }
1197 [WebSysDescription ("Raised before the page containing the control is rendered.")]
1198 public event EventHandler PreRender {
1200 event_mask |= prerender_mask;
1201 Events.AddHandler (PreRenderEvent, value);
1203 remove { Events.RemoveHandler (PreRenderEvent, value); }
1206 [WebSysDescription ("Raised when the page containing the control is unloaded.")]
1207 public event EventHandler Unload {
1209 event_mask |= unload_mask;
1210 Events.AddHandler (UnloadEvent, value);
1212 remove { Events.RemoveHandler (UnloadEvent, value); }
1215 public virtual void DataBind () //DIT
1220 OnDataBinding (EventArgs.Empty);
1229 void DataBindChildren ()
1231 if (!HasControls ())
1234 int len = _controls.Count;
1235 for (int i = 0; i < len; i++) {
1236 Control c = _controls [i];
1241 public virtual bool HasControls ()
1243 return (_controls != null && _controls.Count > 0);
1251 void RenderControl (HtmlTextWriter writer)
1253 if ((stateMask & VISIBLE) != 0) {
1254 HttpContext ctx = Context;
1255 TraceContext trace = (ctx != null) ? ctx.Trace : null;
1257 if ((trace != null) && trace.IsEnabled)
1258 pos = ctx.Response.GetOutputByteCount ();
1261 if ((trace != null) && trace.IsEnabled) {
1262 int size = ctx.Response.GetOutputByteCount () - pos;
1263 trace.SaveSize (this, size >= 0 ? size : 0);
1269 protected void RenderControl (HtmlTextWriter writer, ControlAdapter adapter)
1271 if ((stateMask & VISIBLE) != 0) {
1272 adapter.BeginRender (writer);
1273 adapter.Render (writer);
1274 adapter.EndRender (writer);
1279 public string ResolveUrl (string relativeUrl)
1281 if (relativeUrl == null)
1282 throw new ArgumentNullException ("relativeUrl");
1284 if (relativeUrl == "")
1287 if (relativeUrl [0] == '#')
1290 string ts = TemplateSourceDirectory;
1291 if (ts == null || ts.Length == 0 ||
1292 Context == null || Context.Response == null ||
1293 !UrlUtils.IsRelativeUrl (relativeUrl))
1296 HttpResponse resp = Context.Response;
1297 return resp.ApplyAppPathModifier (UrlUtils.Combine (ts, relativeUrl));
1306 string ResolveClientUrl (string relativeUrl)
1309 // There are no relative paths when rendering a J2EE portlet
1310 if (Page != null && Page.PortletNamespace != null)
1311 return ResolveUrl (relativeUrl);
1313 if (relativeUrl == null)
1314 throw new ArgumentNullException ("relativeUrl");
1316 if (relativeUrl.Length == 0)
1317 return String.Empty;
1319 if (VirtualPathUtility.IsAbsolute (relativeUrl) || relativeUrl.IndexOf (':') >= 0)
1322 HttpContext context = Context;
1323 if (context != null && context.Request != null) {
1324 string templateSourceDirectory = TemplateSourceDirectory;
1325 if (templateSourceDirectory == null || templateSourceDirectory.Length == 0)
1328 string basePath = context.Request.CurrentExecutionFilePath;
1330 if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/')
1331 basePath = VirtualPathUtility.GetDirectory (basePath, false);
1333 if (VirtualPathUtility.IsAppRelative (relativeUrl))
1334 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1336 string templatePath = VirtualPathUtility.AppendTrailingSlash (templateSourceDirectory);
1338 if (basePath.Length == templatePath.Length && String.CompareOrdinal (basePath, templatePath) == 0)
1341 relativeUrl = VirtualPathUtility.Combine (templatePath, relativeUrl);
1342 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1347 internal bool HasRenderMethodDelegate ()
1349 return _renderMethodDelegate != null;
1352 [EditorBrowsable (EditorBrowsableState.Advanced)]
1353 public void SetRenderMethodDelegate (RenderMethod renderMethod) //DIT
1355 _renderMethodDelegate = renderMethod;
1358 internal void LoadRecursive ()
1361 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1362 string type_name = null;
1363 if (trace != null) {
1364 type_name = GetType ().Name;
1365 trace.Write ("control", String.Concat ("LoadRecursive ", _userId, " ", type_name));
1369 if (Adapter != null)
1370 Adapter.OnLoad (EventArgs.Empty);
1373 OnLoad (EventArgs.Empty);
1374 if (HasControls ()) {
1375 int len = _controls.Count;
1376 for (int i = 0; i < len; i++) {
1377 Control c = _controls [i];
1384 trace.Write ("control", String.Concat ("End LoadRecursive ", _userId, " ", type_name));
1386 stateMask |= LOADED;
1389 internal void UnloadRecursive (Boolean dispose)
1392 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1393 string type_name = null;
1394 if (trace != null) {
1395 type_name = GetType ().Name;
1396 trace.Write ("control", String.Concat ("UnloadRecursive ", _userId, " ", type_name));
1399 if (HasControls ()) {
1400 int len = _controls.Count;
1401 for (int i = 0; i < len; i++) {
1402 Control c = _controls [i];
1403 c.UnloadRecursive (dispose);
1409 trace.Write ("control", String.Concat ("End UnloadRecursive ", _userId, " ", type_name));
1412 if (Adapter != null)
1413 Adapter.OnUnload (EventArgs.Empty);
1416 OnUnload (EventArgs.Empty);
1421 internal void PreRenderRecursiveInternal ()
1428 visible = (stateMask & VISIBLE) != 0;
1433 SetMask (VISIBLE, true);
1435 EnsureChildControls ();
1437 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1438 string type_name = null;
1439 if (trace != null) {
1440 type_name = GetType ().Name;
1441 trace.Write ("control", String.Concat ("PreRenderRecursive ", _userId, " ", type_name));
1445 if (Adapter != null)
1446 Adapter.OnPreRender (EventArgs.Empty);
1449 OnPreRender (EventArgs.Empty);
1450 if (!HasControls ())
1453 int len = _controls.Count;
1454 for (int i = 0; i < len; i++) {
1455 Control c = _controls [i];
1456 c.PreRenderRecursiveInternal ();
1460 trace.Write ("control", String.Concat ("End PreRenderRecursive ", _userId, " ", type_name));
1465 SetMask (VISIBLE, false);
1468 stateMask |= PRERENDERED;
1471 internal void InitRecursive (Control namingContainer)
1474 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1475 string type_name = null;
1476 if (trace != null) {
1477 type_name = GetType ().Name;
1478 trace.Write ("control", String.Concat ("InitRecursive ", _userId, " ", type_name));
1481 SetNamingContainer (namingContainer);
1483 if (HasControls ()) {
1484 if ((stateMask & IS_NAMING_CONTAINER) != 0)
1485 namingContainer = this;
1487 int len = _controls.Count;
1488 for (int i = 0; i < len; i++) {
1489 Control c = _controls [i];
1490 c.InitRecursive (namingContainer);
1494 stateMask |= INITING;
1498 if (Adapter != null)
1499 Adapter.OnInit (EventArgs.Empty);
1502 OnInit (EventArgs.Empty);
1505 trace.Write ("control", String.Concat ("End InitRecursive ", _userId, " ", type_name));
1508 stateMask |= INITED;
1509 stateMask &= ~INITING;
1512 internal object SaveViewStateRecursive ()
1514 if (!EnableViewState)
1518 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1519 string type_name = null;
1520 if (trace != null) {
1521 type_name = GetType ().Name;
1522 trace.Write ("control", String.Concat ("SaveViewStateRecursive ", _userId, " ", type_name));
1526 ArrayList controlList = null;
1527 ArrayList controlStates = null;
1530 if (HasControls ()) {
1531 int len = _controls.Count;
1532 for (int i = 0; i < len; i++) {
1533 Control ctrl = _controls [i];
1534 object ctrlState = ctrl.SaveViewStateRecursive ();
1536 if (ctrlState == null)
1539 if (controlList == null) {
1540 controlList = new ArrayList ();
1541 controlStates = new ArrayList ();
1544 controlList.Add (idx);
1545 controlStates.Add (ctrlState);
1549 object thisState = SaveViewState ();
1550 if (thisState == null && controlList == null && controlStates == null) {
1552 if (trace != null) {
1553 trace.Write ("control", "End SaveViewStateRecursive " + _userId + " " + type_name + " saved nothing");
1554 trace.SaveViewState (this, null);
1561 if (trace != null) {
1562 trace.Write ("control", "End SaveViewStateRecursive " + _userId + " " + type_name + " saved a Triplet");
1563 trace.SaveViewState (this, thisState);
1566 return new Triplet (thisState, controlList, controlStates);
1569 internal void LoadViewStateRecursive (object savedState)
1571 if (!EnableViewState || savedState == null)
1575 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 ("LoadViewStateRecursive ", _userId, " ", type_name));
1582 Triplet savedInfo = (Triplet) savedState;
1583 LoadViewState (savedInfo.First);
1585 ArrayList controlList = savedInfo.Second as ArrayList;
1586 if (controlList == null)
1588 ArrayList controlStates = savedInfo.Third as ArrayList;
1589 int nControls = controlList.Count;
1590 for (int i = 0; i < nControls; i++) {
1591 int k = (int) controlList [i];
1592 if (k < Controls.Count && controlStates != null) {
1593 Control c = Controls [k];
1594 c.LoadViewStateRecursive (controlStates [i]);
1597 if (pendingVS == null)
1598 pendingVS = new Hashtable ();
1600 pendingVS [k] = controlStates [i];
1606 trace.Write ("control", String.Concat ("End LoadViewStateRecursive ", _userId, " ", type_name));
1608 stateMask |= VIEWSTATE_LOADED;
1612 internal ControlSkin controlSkin;
1614 internal void ApplyTheme ()
1617 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1618 string type_name = null;
1619 if (trace != null) {
1620 type_name = GetType ().Name;
1621 trace.Write ("control", String.Concat ("ApplyThemeRecursive ", _userId, " ", type_name));
1624 if (Page.PageTheme != null && EnableTheming) {
1625 ControlSkin controlSkin = Page.PageTheme.GetControlSkin (GetType (), SkinID);
1626 if (controlSkin != null)
1627 controlSkin.ApplySkin (this);
1632 trace.Write ("control", String.Concat ("End ApplyThemeRecursive ", _userId, " ", type_name));
1637 internal bool AutoID {
1638 get { return (stateMask & AUTOID) != 0; }
1640 if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
1643 SetMask (AUTOID, value);
1647 protected internal virtual void RemovedControl (Control control)
1649 control.UnloadRecursive (false);
1650 control._parent = null;
1651 control._page = null;
1652 control._namingContainer = null;
1653 if ((control.stateMask & AUTOID_SET) != 0) {
1654 control._userId = null;
1655 control.SetMask (ID_SET, false);
1657 control.NullifyUniqueID ();
1661 string skinId = string.Empty;
1662 bool _enableTheming = true;
1666 [DefaultValue (true)]
1667 public virtual bool EnableTheming {
1669 if ((stateMask & ENABLE_THEMING) != 0)
1670 return _enableTheming;
1672 if (_parent != null)
1673 return _parent.EnableTheming;
1678 SetMask (ENABLE_THEMING, true);
1679 _enableTheming = value;
1685 [Filterable (false)]
1686 public virtual string SkinID {
1687 get { return skinId; }
1688 set { skinId = value; }
1691 ControlBuilder IControlBuilderAccessor.ControlBuilder {
1692 get { throw new NotImplementedException (); }
1695 IDictionary IControlDesignerAccessor.GetDesignModeState ()
1697 throw new NotImplementedException ();
1700 void IControlDesignerAccessor.SetDesignModeState (IDictionary designData)
1702 SetDesignModeState (designData);
1705 void IControlDesignerAccessor.SetOwnerControl (Control control)
1707 throw new NotImplementedException ();
1710 IDictionary IControlDesignerAccessor.UserData {
1711 get { throw new NotImplementedException (); }
1714 ExpressionBindingCollection expressionBindings;
1716 ExpressionBindingCollection IExpressionsAccessor.Expressions {
1718 if (expressionBindings == null)
1719 expressionBindings = new ExpressionBindingCollection ();
1720 return expressionBindings;
1724 bool IExpressionsAccessor.HasExpressions {
1725 get { return (expressionBindings != null && expressionBindings.Count > 0); }
1728 public virtual void Focus ()
1730 Page.SetFocus (this);
1733 protected internal virtual void LoadControlState (object state)
1737 protected internal virtual object SaveControlState ()
1742 protected virtual void DataBind (bool raiseOnDataBinding)
1744 bool foundDataItem = false;
1746 if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
1747 object o = DataBinder.GetDataItem (this, out foundDataItem);
1749 Page.PushDataItemContext (o);
1753 if (raiseOnDataBinding)
1754 OnDataBinding (EventArgs.Empty);
1755 DataBindChildren ();
1758 Page.PopDataItemContext ();
1762 protected virtual IDictionary GetDesignModeState ()
1764 throw new NotImplementedException ();
1767 protected virtual void SetDesignModeState (IDictionary data)
1769 throw new NotImplementedException ();
1772 void IParserAccessor.AddParsedSubObject (object obj)
1774 this.AddParsedSubObject (obj);
1777 DataBindingCollection IDataBindingsAccessor.DataBindings {
1779 if (dataBindings == null) {
1780 dataBindings = new DataBindingCollection ();
1782 return dataBindings;
1786 bool IDataBindingsAccessor.HasDataBindings {
1788 if (dataBindings != null && dataBindings.Count > 0) {