2007-11-03 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.UI / Control.cs
1 //
2 // System.Web.UI.Control.cs
3 //
4 // Authors:
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 //
10 // (C) Bob Smith
11 // (c) 2002,2003 Ximian, Inc. (http://www.ximian.com)
12 // (C) 2004 Novell, Inc. (http://www.novell.com)
13 //
14
15 //
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:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
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.
34 //
35
36 // This will provide extra information when trace is enabled. Might be too verbose.
37 #define MONO_TRACE
38
39 using System.Collections;
40 using System.ComponentModel;
41 using System.ComponentModel.Design;
42 using System.ComponentModel.Design.Serialization;
43 using System.Security.Permissions;
44 using System.Web;
45 using System.Web.Util;
46 using System.Globalization;
47 #if NET_2_0
48 using System.Web.UI.Adapters;
49 using System.IO;
50 #endif
51
52 namespace System.Web.UI
53 {
54         // CAS
55         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
56         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
57         // attributes
58         [DefaultProperty ("ID"), DesignerCategory ("Code"), ToolboxItemFilter ("System.Web.UI", ToolboxItemFilterType.Require)]
59         [ToolboxItem ("System.Web.UI.Design.WebControlToolboxItem, " + Consts.AssemblySystem_Design)]
60         [Designer ("System.Web.UI.Design.ControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
61 #if NET_2_0
62         [DesignerSerializer ("Microsoft.VisualStudio.Web.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VisualStudio_Web,
63                                 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
64         [Bindable (true)]
65         [Themeable (false)]
66 #else
67         [DesignerSerializer ("Microsoft.VSDesigner.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VSDesigner,
68                                 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
69 #endif
70         public partial class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor
71 #if NET_2_0
72 , IUrlResolutionService, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor
73 #endif
74         {
75                 static readonly object DataBindingEvent = new object ();
76                 static readonly object DisposedEvent = new object ();
77                 static readonly object InitEvent = new object ();
78                 static readonly object LoadEvent = new object ();
79                 static readonly object PreRenderEvent = new object ();
80                 static readonly object UnloadEvent = new object ();
81                 static string [] defaultNameArray;
82                 /* */
83                 int event_mask;
84                 const int databinding_mask = 1;
85                 const int disposed_mask = 1 << 1;
86                 const int init_mask = 1 << 2;
87                 const int load_mask = 1 << 3;
88                 const int prerender_mask = 1 << 4;
89                 const int unload_mask = 1 << 5;
90                 /* */
91
92                 string uniqueID;
93                 string _userId;
94                 ControlCollection _controls;
95                 Control _namingContainer;
96                 Page _page;
97                 Control _parent;
98                 ISite _site;
99                 HttpContext _context;
100                 StateBag _viewState;
101                 EventHandlerList _events;
102                 RenderMethod _renderMethodDelegate;
103                 Hashtable _controlsCache;
104                 int defaultNumberID;
105
106                 DataBindingCollection dataBindings;
107                 Hashtable pendingVS; // may hold unused viewstate data from child controls
108
109
110 #if NET_2_0
111                 TemplateControl _templateControl;
112                 bool _isChildControlStateCleared;
113 #endif
114                 string _templateSourceDirectory;
115
116                 /*************/
117                 int stateMask;
118                 const int ENABLE_VIEWSTATE = 1;
119                 const int VISIBLE = 1 << 1;
120                 const int AUTOID = 1 << 2;
121                 const int CREATING_CONTROLS = 1 << 3;
122                 const int BINDING_CONTAINER = 1 << 4;
123                 const int AUTO_EVENT_WIREUP = 1 << 5;
124                 const int IS_NAMING_CONTAINER = 1 << 6;
125                 const int VISIBLE_CHANGED = 1 << 7;
126                 const int TRACK_VIEWSTATE = 1 << 8;
127                 const int CHILD_CONTROLS_CREATED = 1 << 9;
128                 const int ID_SET = 1 << 10;
129                 const int INITED = 1 << 11;
130                 const int INITING = 1 << 12;
131                 const int VIEWSTATE_LOADED = 1 << 13;
132                 const int LOADED = 1 << 14;
133                 const int PRERENDERED = 1 << 15;
134 #if NET_2_0
135                 const int ENABLE_THEMING = 1 << 16;
136 #endif
137                 const int AUTOID_SET = 1 << 17;
138                 /*************/
139
140                 static Control ()
141                 {
142                         defaultNameArray = new string [100];
143                         for (int i = 0; i < 100; i++)
144 #if NET_2_0
145                                 defaultNameArray [i] = String.Format ("ctl{0:D2}", i);
146 #else
147                                 defaultNameArray [i] = "_ctl" + i;
148 #endif
149                 }
150
151                 public Control ()
152                 {
153                         stateMask = ENABLE_VIEWSTATE | VISIBLE | AUTOID | BINDING_CONTAINER | AUTO_EVENT_WIREUP;
154                         if (this is INamingContainer)
155                                 stateMask |= IS_NAMING_CONTAINER;
156                 }
157
158 #if NET_2_0
159                 [MonoTODO ("Not implemented, always returns null")]
160                 protected ControlAdapter Adapter {
161                         get {
162                                 // for the time being, fool the
163                                 // Control machinery into thinking we
164                                 // don't have an Adapter.  This will
165                                 // allow us to write all the rest of
166                                 // the Adapter handling code without
167                                 // having to worry about *having*
168                                 // adapters.
169                                 return null;
170                         }
171                 }
172
173                 string _appRelativeTemplateSourceDirectory = null;
174
175                 [EditorBrowsable (EditorBrowsableState.Advanced)]
176                 [Browsable (false)]
177                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
178                 public string AppRelativeTemplateSourceDirectory {
179                         get {
180                                 if (_appRelativeTemplateSourceDirectory != null)
181                                         return _appRelativeTemplateSourceDirectory;
182
183                                 string tempSrcDir = null;
184
185                                 TemplateControl templateControl = TemplateControl;
186                                 if (templateControl != null)
187                                         if (!string.IsNullOrEmpty (templateControl.AppRelativeVirtualPath))
188                                                 tempSrcDir = VirtualPathUtility.GetDirectory (templateControl.AppRelativeVirtualPath, false);
189
190                                 _appRelativeTemplateSourceDirectory = (tempSrcDir != null) ? tempSrcDir : "~/";
191                                 return _appRelativeTemplateSourceDirectory;
192                         }
193                         [EditorBrowsable (EditorBrowsableState.Never)]
194                         set {
195                                 _appRelativeTemplateSourceDirectory = value;
196                                 _templateSourceDirectory = null;
197                         }
198                 }
199
200 #endif
201
202                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
203                 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
204                 public Control BindingContainer {
205                         get {
206                                 Control container = NamingContainer;
207                                 if (container != null && (container.stateMask & BINDING_CONTAINER) == 0)
208                                         container = container.BindingContainer;
209                                 return container;
210                         }
211                 }
212
213                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
214                 [Browsable (false)]
215                 [WebSysDescription ("An Identification of the control that is rendered.")]
216                 public virtual string ClientID {
217                         get {
218                                 string client = UniqueID;
219
220                                 if (client != null)
221 #if NET_2_0
222                                         client = UniqueID2ClientID (client);
223 #else
224                                         client = client.Replace (':', ClientIDSeparator);
225 #endif
226
227                                 stateMask |= ID_SET;
228                                 return client;
229                         }
230                 }
231
232 #if NET_2_0
233                 internal string UniqueID2ClientID (string uniqueId)
234                 {
235                         return uniqueId.Replace (IdSeparator, ClientIDSeparator);
236                 }
237
238                 protected char ClientIDSeparator
239 #else
240                 char ClientIDSeparator
241 #endif
242                 {
243                         get { return '_'; }
244                 }
245
246
247                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
248                 [Browsable (false)]
249                 [WebSysDescription ("The child controls of this control.")]
250                 public virtual ControlCollection Controls { //DIT
251                         get {
252                                 if (_controls == null)
253                                         _controls = CreateControlCollection ();
254                                 return _controls;
255                         }
256                 }
257
258 #if NET_2_0
259                 [MonoTODO ("revisit once we have a real design strategy")]
260                 protected internal bool DesignMode {
261                         get { return false; }
262                 }
263 #endif
264
265                 [DefaultValue (true), WebCategory ("Behavior")]
266                 [WebSysDescription ("An Identification of the control that is rendered.")]
267 #if NET_2_0
268                 [Themeable (false)]
269 #endif
270                 public virtual bool EnableViewState {
271                         get { return ((stateMask & ENABLE_VIEWSTATE) != 0); }
272                         set { SetMask (ENABLE_VIEWSTATE, value); }
273                 }
274
275                 [MergableProperty (false), ParenthesizePropertyName (true)]
276                 [WebSysDescription ("The name of the control that is rendered.")]
277 #if NET_2_0
278                 [Filterable (false), Themeable (false)]
279 #endif
280
281                 public virtual string ID {
282                         get { return (((stateMask & ID_SET) != 0) ? _userId : null); }
283
284                         set {
285                                 if (value == "")
286                                         value = null;
287
288                                 stateMask |= ID_SET;
289                                 _userId = value;
290                                 NullifyUniqueID ();
291                         }
292                 }
293
294 #if NET_2_0
295                 protected char IdSeparator {
296                         get { return '$'; }
297                 }
298
299                 protected internal bool IsChildControlStateCleared {
300                         get { return _isChildControlStateCleared; }
301                 }
302
303                 protected internal bool IsViewStateEnabled {
304                         get {
305                                 for (Control control = this; control != null; control = control.Parent)
306                                         if (!control.EnableViewState)
307                                                 return false;
308
309                                 return true;
310                         }
311                 }
312
313                 protected bool LoadViewStateByID {
314                         get { return false; }
315                 }
316 #endif
317
318                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
319                 [Browsable (false)]
320                 [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]
321                 public virtual Control NamingContainer {
322                         get {
323                                 if (_namingContainer == null && _parent != null) {
324                                         if ((_parent.stateMask & IS_NAMING_CONTAINER) == 0)
325                                                 _namingContainer = _parent.NamingContainer;
326                                         else
327                                                 _namingContainer = _parent;
328                                 }
329
330                                 return _namingContainer;
331                         }
332                 }
333
334                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
335                 [Browsable (false)]
336                 [WebSysDescription ("The webpage that this control resides on.")]
337 #if NET_2_0
338                 [Bindable (false)]
339 #endif
340                 public virtual Page Page { //DIT
341                         get {
342                                 if (_page == null){
343                                         if (NamingContainer != null)
344                                                 _page = NamingContainer.Page;
345                                         else if (Parent != null)
346                                                 _page = Parent.Page;
347                                 }
348                                 return _page;
349                         }
350                         
351                         set { _page = value; }
352                 }
353
354                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
355                 [Browsable (false)]
356                 [WebSysDescription ("The parent control of this control.")]
357                 public virtual Control Parent { //DIT
358                         get { return _parent; }
359                 }
360
361                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
362                 [EditorBrowsable (EditorBrowsableState.Advanced), Browsable (false)]
363                 [WebSysDescription ("The site this control is part of.")]
364                 public ISite Site { //DIT
365                         get { return _site; }
366                         set { _site = value; }
367                 }
368
369 #if NET_2_0
370                 [Browsable (false)]
371                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
372                 public TemplateControl TemplateControl {
373                         get { return TemplateControlInternal; }
374
375                         [EditorBrowsable (EditorBrowsableState.Never)]
376                         set { _templateControl = value; }
377                 }
378
379                 internal virtual TemplateControl TemplateControlInternal {
380                         get {
381                                 if (_templateControl != null)
382                                         return _templateControl;
383                                 if (_parent != null)
384                                         return _parent.TemplateControl;
385                                 return null;
386                         }
387                 }
388 #endif
389
390 #if !TARGET_J2EE
391                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
392                 [Browsable (false)]
393                 [WebSysDescription ("A virtual directory containing the parent of the control.")]
394                 public virtual string TemplateSourceDirectory {
395                         get {
396 #if NET_2_0
397                                 if (_templateSourceDirectory == null) {
398                                         TemplateControl tc = TemplateControl;
399
400                                         if (tc == null) {
401                                                 HttpContext ctx = Context;
402                                                 if (ctx != null)
403                                                         _templateSourceDirectory = VirtualPathUtility.GetDirectory (ctx.Request.CurrentExecutionFilePath);
404                                         } else if (tc != this)
405                                                 _templateSourceDirectory = tc.TemplateSourceDirectory;
406
407                                         if (_templateSourceDirectory == null && this is TemplateControl) {
408                                                 string path = ((TemplateControl) this).AppRelativeVirtualPath;
409
410                                                 if (path != null) {
411                                                         // Pretend our application virtual root is "/" even if it isn't - we just
412                                                         // want to get an absolute url out of relative one, without the real
413                                                         // application root prepended to it.
414                                                         string ret = VirtualPathUtility.GetDirectory (VirtualPathUtility.ToAbsolute (path, "/"));
415                                                         int len = ret.Length;
416                                                         if (len <= 1)
417                                                                 return ret;
418                                                         if (ret [--len] == '/')
419                                                                 _templateSourceDirectory = ret.Substring (0, len);
420                                                 } else
421                                                         _templateSourceDirectory = String.Empty;
422                                         }
423                                         if (_templateSourceDirectory == null)
424                                                 _templateSourceDirectory = String.Empty;
425                                 }
426
427                                 return _templateSourceDirectory;
428 #else
429                                 if (_templateSourceDirectory == null) {
430                                         HttpContext ctx = HttpContext.Current;
431                                         HttpRequest req = ctx != null ? ctx.Request : null;
432                                         
433                                         _templateSourceDirectory = (_parent == null)
434                                                 ? req != null ? VirtualPathUtility.RemoveTrailingSlash (
435                                                         VirtualPathUtility.GetDirectory (
436                                                                 HttpContext.Current.Request.CurrentExecutionFilePath)) : String.Empty
437                                                 : _parent.TemplateSourceDirectory;
438                                 }
439                                 return _templateSourceDirectory;
440 #endif
441                         }
442                 }
443 #endif
444
445                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
446                 [Browsable (false)]
447                 [WebSysDescription ("The unique ID of the control.")]
448                 public virtual string UniqueID {
449                         get {
450                                 if (uniqueID != null)
451                                         return uniqueID;
452
453                                 if (NamingContainer == null)
454                                         return _userId;
455
456                                 EnsureIDInternal ();
457
458                                 string prefix = NamingContainer.UniqueID;
459 #if TARGET_J2EE
460                                 // For J2EE portlets we need to add the namespace to the ID.
461                                 if (NamingContainer == Page && Page.PortletNamespace != null)
462                                         prefix = Page.PortletNamespace;
463                                 else
464 #endif
465                                 if (NamingContainer == Page || prefix == null) {
466                                         uniqueID = _userId;
467                                         return uniqueID;
468                                 }
469
470 #if NET_2_0
471                                 uniqueID = prefix + IdSeparator + _userId;
472 #else
473                                 uniqueID = prefix + ":" + _userId;
474 #endif
475                                 return uniqueID;
476                         }
477                 }
478
479                 void SetMask (int m, bool val) {
480                         if (val)
481                                 stateMask |= m;
482                         else
483                                 stateMask &= ~m;
484                 }
485
486                 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
487                 [WebSysDescription ("Visiblity state of the control.")]
488                 public virtual bool Visible {
489                         get {
490                                 if ((stateMask & VISIBLE) == 0)
491                                         return false;
492
493                                 if (_parent != null)
494                                         return _parent.Visible;
495
496                                 return true;
497                         }
498
499                         set {
500                                 if ((value && (stateMask & VISIBLE) == 0) ||
501                                         (!value && (stateMask & VISIBLE) != 0)) {
502                                         if (IsTrackingViewState)
503                                                 stateMask |= VISIBLE_CHANGED;
504                                 }
505
506                                 SetMask (VISIBLE, value);
507                         }
508                 }
509
510                 protected bool ChildControlsCreated {
511                         get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
512                         set {
513                                 if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
514                                         if (_controls != null)
515                                                 _controls.Clear ();
516                                 }
517
518                                 SetMask (CHILD_CONTROLS_CREATED, value);
519                         }
520                 }
521
522                 [Browsable (false)]
523                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
524                 protected virtual HttpContext Context { //DIT
525                         get {
526                                 HttpContext context;
527                                 if (_context != null)
528                                         return _context;
529                                 if (_parent == null)
530                                         return HttpContext.Current;
531                                 context = _parent.Context;
532                                 if (context != null)
533                                         return context;
534                                 return HttpContext.Current;
535                         }
536                 }
537
538                 protected EventHandlerList Events {
539                         get {
540                                 if (_events == null)
541                                         _events = new EventHandlerList ();
542                                 return _events;
543                         }
544                 }
545
546                 protected bool HasChildViewState {
547                         get { return (pendingVS != null && pendingVS.Count > 0); }
548                 }
549
550                 protected bool IsTrackingViewState {
551                         get { return ((stateMask & TRACK_VIEWSTATE) != 0); }
552                 }
553
554                 [Browsable (false)]
555                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
556                 [WebSysDescription ("ViewState")]
557                 protected virtual StateBag ViewState {
558                         get {
559                                 if (_viewState == null)
560                                         _viewState = new StateBag (ViewStateIgnoresCase);
561
562                                 if (IsTrackingViewState)
563                                         _viewState.TrackViewState ();
564
565                                 return _viewState;
566                         }
567                 }
568
569                 [Browsable (false)]
570                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
571                 protected virtual bool ViewStateIgnoresCase {
572                         get { return false; }
573                 }
574
575                 internal bool AutoEventWireup {
576                         get { return (stateMask & AUTO_EVENT_WIREUP) != 0; }
577                         set { SetMask (AUTO_EVENT_WIREUP, value); }
578                 }
579
580                 internal void SetBindingContainer (bool isBC)
581                 {
582                         SetMask (BINDING_CONTAINER, isBC);
583                 }
584
585                 internal void ResetChildNames ()
586                 {
587                         defaultNumberID = 0;
588                 }
589
590                 string GetDefaultName ()
591                 {
592                         string defaultName;
593                         if (defaultNumberID > 99) {
594 #if NET_2_0
595                                 defaultName = "ctl" + defaultNumberID++;
596 #else
597                                 defaultName = "_ctl" + defaultNumberID++;
598 #endif
599                         } else {
600                                 defaultName = defaultNameArray [defaultNumberID++];
601                         }
602                         return defaultName;
603                 }
604
605                 void NullifyUniqueID ()
606                 {
607                         uniqueID = null;
608                         if (!HasControls ())
609                                 return;
610
611                         for (int i = 0; i < _controls.Count; i++)
612                                 _controls [i].NullifyUniqueID ();
613                 }
614
615                 protected internal virtual void AddedControl (Control control, int index)
616                 {
617                         ResetControlsCache ();
618
619                         /* Ensure the control don't have more than 1 parent */
620                         if (control._parent != null)
621                                 control._parent.Controls.Remove (control);
622
623                         control._parent = this;
624                         Control nc = ((stateMask & IS_NAMING_CONTAINER) != 0) ? this : NamingContainer;
625
626                         if ((stateMask & (INITING | INITED)) != 0)
627                                 control.InitRecursive (nc);
628                         else {
629                                 control.SetNamingContainer (nc);
630                                 return;
631                         }
632
633                         if ((stateMask & (VIEWSTATE_LOADED | LOADED)) != 0) {
634                                 if (pendingVS != null) {
635                                         object vs = pendingVS [index];
636                                         if (vs != null) {
637                                                 pendingVS.Remove (index);
638                                                 if (pendingVS.Count == 0)
639                                                         pendingVS = null;
640
641                                                 control.LoadViewStateRecursive (vs);
642                                         }
643                                 }
644                         }
645
646                         if ((stateMask & LOADED) != 0)
647                                 control.LoadRecursive ();
648
649                         if ((stateMask & PRERENDERED) != 0)
650                                 control.PreRenderRecursiveInternal ();
651                 }
652                 
653                 void SetNamingContainer (Control nc)
654                 {
655                         if (nc != null) {
656                                 _namingContainer = nc;
657                                 if (AutoID)
658                                         EnsureIDInternal ();
659                         }
660                 }
661
662                 protected virtual void AddParsedSubObject (object obj) //DIT
663                 {
664                         Control c = obj as Control;
665                         if (c != null)
666                                 Controls.Add (c);
667                 }
668
669 #if NET_2_0
670                 [EditorBrowsable (EditorBrowsableState.Advanced)]
671                 public virtual void ApplyStyleSheetSkin (Page page)
672                 {
673                         if (!EnableTheming) /* this enough? */
674                                 return;
675
676                         /* apply the style sheet skin here */
677                         if (page.StyleSheetPageTheme != null) {
678                                 ControlSkin cs = page.StyleSheetPageTheme.GetControlSkin (GetType (), SkinID);
679                                 if (cs != null)
680                                         cs.ApplySkin (this);
681                         }
682                 }
683 #endif
684
685                 protected void BuildProfileTree (string parentId, bool calcViewState)
686                 {
687                         //TODO
688                 }
689
690 #if NET_2_0
691                 protected void ClearChildControlState ()
692                 {
693                         _isChildControlStateCleared = true;
694                 }
695
696                 protected void ClearChildState ()
697                 {
698                         ClearChildViewState ();
699                         ClearChildControlState ();
700                 }
701 #endif
702
703                 protected void ClearChildViewState ()
704                 {
705                         pendingVS = null;
706                 }
707
708 #if NET_2_0
709                 protected internal
710 #else
711                 protected
712 #endif
713                 virtual void CreateChildControls () //DIT
714                 {
715                 }
716
717                 protected virtual ControlCollection CreateControlCollection () //DIT
718                 {
719                         return new ControlCollection (this);
720                 }
721
722                 protected virtual void EnsureChildControls ()
723                 {
724                         if (ChildControlsCreated == false && (stateMask & CREATING_CONTROLS) == 0) {
725                                 stateMask |= CREATING_CONTROLS;
726 #if NET_2_0
727                                 if (Adapter != null)
728                                         Adapter.CreateChildControls ();
729                                 else
730 #endif
731                                         CreateChildControls ();
732                                 ChildControlsCreated = true;
733                                 stateMask &= ~CREATING_CONTROLS;
734                         }
735                 }
736
737                 void EnsureIDInternal ()
738                 {
739                         if (_userId != null)
740                                 return;
741
742                         _userId = NamingContainer.GetDefaultName ();
743                         SetMask (AUTOID_SET, true);
744                 }
745
746 #if NET_2_0
747                 protected void EnsureID ()
748                 {
749                         if (NamingContainer == null)
750                                 return;
751                         EnsureIDInternal ();
752                         SetMask (ID_SET, true);
753                 }
754
755                 protected bool HasEvents ()
756                 {
757                         return _events != null;
758                 }
759 #endif
760
761                 void ResetControlsCache ()
762                 {
763                         _controlsCache = null;
764
765                         if ((this.stateMask & IS_NAMING_CONTAINER) == 0 && Parent != null)
766                                 Parent.ResetControlsCache ();
767                 }
768
769                 Hashtable InitControlsCache ()
770                 {
771                         if (_controlsCache != null)
772                                 return _controlsCache;
773
774                         if ((this.stateMask & IS_NAMING_CONTAINER) != 0 || Parent == null)
775                                 //LAMESPEC: MS' docs don't mention it, but FindControl is case insensitive.
776 #if NET_2_0
777                                 _controlsCache = new Hashtable (StringComparer.OrdinalIgnoreCase);
778 #else
779                                 _controlsCache = new Hashtable (CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);
780 #endif
781                         else
782                                 _controlsCache = Parent.InitControlsCache ();
783
784                         return _controlsCache;
785                 }
786
787                 void EnsureControlsCache ()
788                 {
789                         if (_controlsCache != null)
790                                 return;
791
792                         InitControlsCache ();
793                         FillControlCache (this);
794
795                 }
796
797                 void FillControlCache (Control control)
798                 {
799                         if (!HasControls ())
800                                 return;
801
802                         foreach (Control c in control._controls) {
803                                 try {
804                                         if (c._userId != null)
805                                                 _controlsCache.Add (c._userId, c);
806                                 } catch (Exception ex) {
807                                         throw new HttpException ("Found more than one control with ID '" + c._userId + "'", ex);
808                                 }
809
810                                 if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ())
811                                         FillControlCache (c);
812                         }
813                 }
814
815                 protected bool IsLiteralContent ()
816                 {
817                         if (HasControls () && _controls.Count == 1 && (_controls [0] is LiteralControl))
818                                 return true;
819
820                         return false;
821                 }
822
823                 [WebSysDescription ("")]
824                 public virtual Control FindControl (string id)
825                 {
826                         return FindControl (id, 0);
827                 }
828
829                 Control LookForControlByName (string id)
830                 {
831 #if TARGET_J2EE
832                         if (this == Page && id != null && id == Page.PortletNamespace)
833                                 return this;
834 #endif
835                         EnsureControlsCache ();
836                         return (Control) _controlsCache [id];
837                 }
838
839                 protected virtual Control FindControl (string id, int pathOffset)
840                 {
841                         EnsureChildControls ();
842                         Control namingContainer = null;
843                         if ((stateMask & IS_NAMING_CONTAINER) == 0) {
844                                 namingContainer = NamingContainer;
845                                 if (namingContainer == null)
846                                         return null;
847
848                                 return namingContainer.FindControl (id, pathOffset);
849                         }
850
851                         if (!HasControls ())
852                                 return null;
853 #if NET_2_0
854                         int separatorIdx = id.IndexOf (IdSeparator, pathOffset);
855 #else
856                         int separatorIdx = id.IndexOf (':', pathOffset);
857 #endif
858                         if (separatorIdx == -1)
859                                 return LookForControlByName (id.Substring (pathOffset));
860
861                         string idfound = id.Substring (pathOffset, separatorIdx - pathOffset);
862                         namingContainer = LookForControlByName (idfound);
863                         if (namingContainer == null)
864                                 return null;
865
866                         return namingContainer.FindControl (id, separatorIdx + 1);
867                 }
868
869                 protected virtual void LoadViewState (object savedState)
870                 {
871                         if (savedState != null) {
872                                 ViewState.LoadViewState (savedState);
873                                 object o = ViewState ["Visible"];
874                                 if (o != null) {
875                                         SetMask (VISIBLE, (bool) o);
876                                         stateMask |= VISIBLE_CHANGED;
877                                 }
878                         }
879                 }
880
881                 // [MonoTODO("Secure?")]
882                 protected string MapPathSecure (string virtualPath)
883                 {
884                         string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
885                         return Context.Request.MapPath (combined);
886                 }
887
888                 protected virtual bool OnBubbleEvent (object source, EventArgs args) //DIT
889                 {
890 #if MONO_TRACE
891                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
892                         string type_name = null;
893                         if (trace != null) {
894                                 type_name = GetType ().Name;
895                                 trace.Write ("control", String.Format ("OnBubbleEvent {0} {1}", _userId, type_name));
896                         }
897 #endif
898                         return false;
899                 }
900
901                 protected virtual void OnDataBinding (EventArgs e)
902                 {
903                         if ((event_mask & databinding_mask) != 0) {
904                                 EventHandler eh = (EventHandler) (_events [DataBindingEvent]);
905                                 if (eh != null) {
906 #if MONO_TRACE
907                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
908                                         string type_name = null;
909                                         if (trace != null) {
910                                                 type_name = GetType ().Name;
911                                                 trace.Write ("control", String.Format ("OnDataBinding {0} {1}", _userId, type_name));
912                                         }
913 #endif
914                                         eh (this, e);
915                                 }
916                         }
917                 }
918
919 #if NET_2_0
920                 protected internal
921 #else           
922                 protected
923 #endif
924                 virtual void OnInit (EventArgs e)
925                 {
926                         if ((event_mask & init_mask) != 0) {
927                                 EventHandler eh = (EventHandler) (_events [InitEvent]);
928                                 if (eh != null) {
929 #if MONO_TRACE
930                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
931                                         string type_name = null;
932                                         if (trace != null) {
933                                                 type_name = GetType ().Name;
934                                                 trace.Write ("control", String.Format ("OnInit {0} {1}", _userId, type_name));
935                                         }
936 #endif
937                                         eh (this, e);
938                                 }
939                         }
940                 }
941
942 #if NET_2_0
943                 protected internal
944 #else
945                 protected
946 #endif
947                 virtual void OnLoad (EventArgs e)
948                 {
949                         if ((event_mask & load_mask) != 0) {
950                                 EventHandler eh = (EventHandler) (_events [LoadEvent]);
951                                 if (eh != null) {
952 #if MONO_TRACE
953                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
954                                         string type_name = null;
955                                         if (trace != null) {
956                                                 type_name = GetType ().Name;
957                                                 trace.Write ("control", String.Format ("OnLoad {0} {1}", _userId, type_name));
958                                         }
959 #endif
960                                         eh (this, e);
961                                 }
962                         }
963                 }
964
965 #if NET_2_0
966                 protected internal
967 #else
968                 protected
969 #endif
970                 virtual void OnPreRender (EventArgs e)
971                 {
972                         if ((event_mask & prerender_mask) != 0) {
973                                 EventHandler eh = (EventHandler) (_events [PreRenderEvent]);
974                                 if (eh != null) {
975 #if MONO_TRACE
976                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
977                                         string type_name = null;
978                                         if (trace != null) {
979                                                 type_name = GetType ().Name;
980                                                 trace.Write ("control", String.Format ("OnPreRender {0} {1}", _userId, type_name));
981                                         }
982 #endif
983                                         eh (this, e);
984                                 }
985                         }
986                 }
987
988 #if NET_2_0
989                 protected internal
990 #else
991                 protected
992 #endif
993                 virtual void OnUnload (EventArgs e)
994                 {
995                         if ((event_mask & unload_mask) != 0) {
996                                 EventHandler eh = (EventHandler) (_events [UnloadEvent]);
997                                 if (eh != null) {
998 #if MONO_TRACE
999                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1000                                         string type_name = null;
1001                                         if (trace != null) {
1002                                                 type_name = GetType ().Name;
1003                                                 trace.Write ("control", String.Format ("OnUnload {0} {1}", _userId, type_name));
1004                                         }
1005 #endif
1006                                         eh (this, e);
1007                                 }
1008                         }
1009                 }
1010
1011 #if NET_2_0
1012                 protected internal Stream OpenFile (string path)
1013                 {
1014                         try {
1015                                 string filePath = Context.Server.MapPath (path);
1016                                 return File.OpenRead (filePath);
1017                         }
1018                         catch (UnauthorizedAccessException) {
1019                                 throw new HttpException ("Access to the specified file was denied.");
1020                         }
1021                 }
1022
1023                 internal string GetPhysicalFilePath (string virtualPath)
1024                 {
1025                         Page page = Page;
1026
1027                         if (VirtualPathUtility.IsAbsolute (virtualPath))
1028                                 return page != null ? page.MapPath (virtualPath) : Context.Server.MapPath (virtualPath);
1029
1030                         // We need to determine whether one of our parents is a
1031                         // master page. If so, we need to map the path
1032                         // relatively to the master page and not our containing
1033                         // page/control. This is necessary for cases when a
1034                         // relative path is used in a control placed in a master
1035                         // page and the master page is referenced from a
1036                         // location other than its own. In such cases MS.NET looks
1037                         // for the file in the directory where the master page
1038                         // is.
1039                         //
1040                         // An example of where it is needed is at
1041                         //
1042                         // http://quickstarts.asp.net/QuickStartv20/aspnet/samples/masterpages/masterpages_cs/pages/default.aspx
1043                         //
1044                         MasterPage master = null;
1045                         Control ctrl = Parent;
1046
1047                         while (ctrl != null) {
1048                                 if (ctrl is MasterPage) {
1049                                         master = ctrl as MasterPage;
1050                                         break;
1051                                 }
1052                                 ctrl = ctrl.Parent;
1053                         }
1054
1055                         string path;
1056                         if (master != null)
1057                                 path = VirtualPathUtility.Combine (master.TemplateSourceDirectory, virtualPath);
1058                         else
1059                                 path = VirtualPathUtility.Combine (TemplateSourceDirectory, virtualPath);
1060                         return page != null ? page.MapPath (path) : Context.Server.MapPath (path);
1061                 }
1062 #endif
1063
1064                 protected void RaiseBubbleEvent (object source, EventArgs args)
1065                 {
1066                         Control c = Parent;
1067                         while (c != null) {
1068 #if MONO_TRACE
1069                                 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1070                                 string type_name = null;
1071                                 if (trace != null) {
1072                                         type_name = GetType ().Name;
1073                                         trace.Write ("control", String.Format ("RaiseBubbleEvent {0} {1}", _userId, type_name));
1074                                 }
1075 #endif
1076                                 if (c.OnBubbleEvent (source, args)) {
1077 #if MONO_TRACE
1078                                         if (trace != null)
1079                                                 trace.Write ("control", String.Format ("End RaiseBubbleEvent (false) {0} {1}", _userId, type_name));
1080 #endif
1081                                         break;
1082                                 }
1083 #if MONO_TRACE
1084                                 if (trace != null)
1085                                         trace.Write ("control", String.Format ("End RaiseBubbleEvent (true) {0} {1}", _userId, type_name));
1086 #endif
1087                                 c = c.Parent;
1088                         }
1089                 }
1090
1091 #if NET_2_0
1092                 protected internal
1093 #else
1094                 protected
1095 #endif
1096                 virtual void Render (HtmlTextWriter writer) //DIT
1097                 {
1098                         RenderChildren (writer);
1099                 }
1100
1101 #if NET_2_0
1102                 protected internal
1103 #else
1104                 protected
1105 #endif
1106                 virtual void RenderChildren (HtmlTextWriter writer) //DIT
1107                 {
1108                         if (_renderMethodDelegate != null) {
1109                                 _renderMethodDelegate (writer, this);
1110                         } else if (_controls != null) {
1111                                 int len = _controls.Count;
1112                                 Control c;
1113                                 for (int i = 0; i < len; i++) {
1114                                         c = _controls [i];
1115                                         if (c == null)
1116                                                 continue;
1117 #if NET_2_0
1118                                         if (c.Adapter != null)
1119                                                 c.RenderControl (writer, c.Adapter);
1120                                         else
1121 #endif
1122                                                 c.RenderControl (writer);
1123                                 }
1124                         }
1125                 }
1126
1127 #if NET_2_0
1128                 protected virtual ControlAdapter ResolveAdapter ()
1129                 {
1130                         throw new NotImplementedException ();
1131                 }
1132 #endif
1133
1134                 protected virtual object SaveViewState ()
1135                 {
1136                         if ((stateMask & VISIBLE_CHANGED) != 0) {
1137                                 ViewState ["Visible"] = (stateMask & VISIBLE) != 0;
1138                         } else if (_viewState == null) {
1139                                 return null;
1140                         }
1141
1142                         return _viewState.SaveViewState ();
1143                 }
1144
1145                 protected virtual void TrackViewState ()
1146                 {
1147                         if (_viewState != null)
1148                                 _viewState.TrackViewState ();
1149
1150                         stateMask |= TRACK_VIEWSTATE;
1151                 }
1152
1153                 public virtual void Dispose ()
1154                 {
1155                         if ((event_mask & disposed_mask) != 0) {
1156                                 EventHandler eh = (EventHandler) (_events [DisposedEvent]);
1157                                 if (eh != null)
1158                                         eh (this, EventArgs.Empty);
1159                         }
1160                 }
1161
1162                 [WebCategory ("FIXME")]
1163                 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]
1164                 public event EventHandler DataBinding {
1165                         add {
1166                                 event_mask |= databinding_mask;
1167                                 Events.AddHandler (DataBindingEvent, value);
1168                         }
1169                         remove { Events.RemoveHandler (DataBindingEvent, value); }
1170                 }
1171
1172                 [WebSysDescription ("Raised when the contol is disposed.")]
1173                 public event EventHandler Disposed {
1174                         add {
1175                                 event_mask |= disposed_mask;
1176                                 Events.AddHandler (DisposedEvent, value);
1177                         }
1178                         remove { Events.RemoveHandler (DisposedEvent, value); }
1179                 }
1180
1181                 [WebSysDescription ("Raised when the page containing the control is initialized.")]
1182                 public event EventHandler Init {
1183                         add {
1184                                 event_mask |= init_mask;
1185                                 Events.AddHandler (InitEvent, value);
1186                         }
1187                         remove { Events.RemoveHandler (InitEvent, value); }
1188                 }
1189
1190                 [WebSysDescription ("Raised after the page containing the control has been loaded.")]
1191                 public event EventHandler Load {
1192                         add {
1193                                 event_mask |= load_mask;
1194                                 Events.AddHandler (LoadEvent, value);
1195                         }
1196                         remove { Events.RemoveHandler (LoadEvent, value); }
1197                 }
1198
1199                 [WebSysDescription ("Raised before the page containing the control is rendered.")]
1200                 public event EventHandler PreRender {
1201                         add {
1202                                 event_mask |= prerender_mask;
1203                                 Events.AddHandler (PreRenderEvent, value);
1204                         }
1205                         remove { Events.RemoveHandler (PreRenderEvent, value); }
1206                 }
1207
1208                 [WebSysDescription ("Raised when the page containing the control is unloaded.")]
1209                 public event EventHandler Unload {
1210                         add {
1211                                 event_mask |= unload_mask;
1212                                 Events.AddHandler (UnloadEvent, value);
1213                         }
1214                         remove { Events.RemoveHandler (UnloadEvent, value); }
1215                 }
1216
1217                 public virtual void DataBind () //DIT
1218                 {
1219 #if NET_2_0
1220                         DataBind (true);
1221 #else
1222                         OnDataBinding (EventArgs.Empty);
1223                         DataBindChildren();
1224 #endif
1225                 }
1226
1227 #if NET_2_0
1228                 protected virtual
1229 #endif
1230
1231                 void DataBindChildren ()
1232                 {
1233                         if (!HasControls ())
1234                                 return;
1235
1236                         int len = _controls.Count;
1237                         for (int i = 0; i < len; i++) {
1238                                 Control c = _controls [i];
1239                                 c.DataBind ();
1240                         }
1241                 }
1242
1243                 public virtual bool HasControls ()
1244                 {
1245                         return (_controls != null && _controls.Count > 0);
1246                 }
1247
1248 #if NET_2_0
1249                 public virtual
1250 #else
1251                 public
1252 #endif
1253                 void RenderControl (HtmlTextWriter writer)
1254                 {
1255                         if ((stateMask & VISIBLE) != 0) {
1256                                 HttpContext ctx = Context;
1257                                 TraceContext trace = (ctx != null) ? ctx.Trace : null;
1258                                 int pos = 0;
1259                                 if ((trace != null) && trace.IsEnabled)
1260                                         pos = ctx.Response.GetOutputByteCount ();
1261
1262                                 Render (writer);
1263                                 if ((trace != null) && trace.IsEnabled) {
1264                                         int size = ctx.Response.GetOutputByteCount () - pos;
1265                                         trace.SaveSize (this, size >= 0 ? size : 0);
1266                                 }
1267                         }
1268                 }
1269
1270 #if NET_2_0
1271                 protected void RenderControl (HtmlTextWriter writer, ControlAdapter adapter)
1272                 {
1273                         if ((stateMask & VISIBLE) != 0) {
1274                                 adapter.BeginRender (writer);
1275                                 adapter.Render (writer);
1276                                 adapter.EndRender (writer);
1277                         }
1278                 }
1279 #endif
1280
1281                 public string ResolveUrl (string relativeUrl)
1282                 {
1283                         if (relativeUrl == null)
1284                                 throw new ArgumentNullException ("relativeUrl");
1285
1286                         if (relativeUrl == "")
1287                                 return "";
1288
1289                         if (relativeUrl [0] == '#')
1290                                 return relativeUrl;
1291
1292                         string ts = TemplateSourceDirectory;
1293                         if (ts == null || ts.Length == 0 ||
1294                                 Context == null || Context.Response == null ||
1295                                 !UrlUtils.IsRelativeUrl (relativeUrl))
1296                                 return relativeUrl;
1297
1298                         HttpResponse resp = Context.Response;
1299                         return resp.ApplyAppPathModifier (UrlUtils.Combine (ts, relativeUrl));
1300                 }
1301
1302
1303 #if NET_2_0
1304                 public
1305 #else
1306                 internal
1307 #endif
1308                 string ResolveClientUrl (string relativeUrl)
1309                 {
1310 #if TARGET_J2EE
1311                         // There are no relative paths when rendering a J2EE portlet
1312                         if (Page != null && Page.PortletNamespace != null)
1313                                 return ResolveUrl (relativeUrl);
1314 #endif
1315                         if (relativeUrl == null)
1316                                 throw new ArgumentNullException ("relativeUrl");
1317
1318                         if (relativeUrl.Length == 0)
1319                                 return String.Empty;
1320
1321                         if (VirtualPathUtility.IsAbsolute (relativeUrl) || relativeUrl.IndexOf (':') >= 0)
1322                                 return relativeUrl;
1323
1324                         HttpContext context = Context;
1325                         if (context != null && context.Request != null) {
1326                                 string templateSourceDirectory = TemplateSourceDirectory;
1327                                 if (templateSourceDirectory == null || templateSourceDirectory.Length == 0)
1328                                         return relativeUrl;
1329
1330                                 string basePath = context.Request.CurrentExecutionFilePath;
1331
1332                                 if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/')
1333                                         basePath = VirtualPathUtility.GetDirectory (basePath, false);
1334
1335                                 if (VirtualPathUtility.IsAppRelative (relativeUrl))
1336                                         return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1337
1338                                 string templatePath = VirtualPathUtility.AppendTrailingSlash (templateSourceDirectory);
1339
1340                                 if (basePath.Length == templatePath.Length && String.CompareOrdinal (basePath, templatePath) == 0)
1341                                         return relativeUrl;
1342
1343                                 relativeUrl = VirtualPathUtility.Combine (templatePath, relativeUrl);
1344                                 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1345                         }
1346                         return relativeUrl;
1347                 }
1348
1349                 internal bool HasRenderMethodDelegate ()
1350                 {
1351                         return _renderMethodDelegate != null;
1352                 }
1353
1354                 [EditorBrowsable (EditorBrowsableState.Advanced)]
1355                 public void SetRenderMethodDelegate (RenderMethod renderMethod) //DIT
1356                 {
1357                         _renderMethodDelegate = renderMethod;
1358                 }
1359
1360                 internal void LoadRecursive ()
1361                 {
1362 #if MONO_TRACE
1363                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1364                         string type_name = null;
1365                         if (trace != null) {
1366                                 type_name = GetType ().Name;
1367                                 trace.Write ("control", String.Format ("LoadRecursive {0} {1}", _userId, type_name));
1368                         }
1369 #endif
1370 #if NET_2_0
1371                         if (Adapter != null)
1372                                 Adapter.OnLoad (EventArgs.Empty);
1373                         else
1374 #endif
1375                                 OnLoad (EventArgs.Empty);
1376                         if (HasControls ()) {
1377                                 int len = _controls.Count;
1378                                 for (int i = 0; i < len; i++) {
1379                                         Control c = _controls [i];
1380                                         c.LoadRecursive ();
1381                                 }
1382                         }
1383
1384 #if MONO_TRACE
1385                         if (trace != null)
1386                                 trace.Write ("control", String.Format ("End LoadRecursive {0} {1}", _userId, type_name));
1387 #endif
1388                         stateMask |= LOADED;
1389                 }
1390
1391                 internal void UnloadRecursive (Boolean dispose)
1392                 {
1393 #if MONO_TRACE
1394                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1395                         string type_name = null;
1396                         if (trace != null) {
1397                                 type_name = GetType ().Name;
1398                                 trace.Write ("control", String.Format ("UnloadRecursive {0} {1}", _userId, type_name));
1399                         }
1400 #endif
1401                         if (HasControls ()) {
1402                                 int len = _controls.Count;
1403                                 for (int i = 0; i < len; i++) {
1404                                         Control c = _controls [i];
1405                                         c.UnloadRecursive (dispose);
1406                                 }
1407                         }
1408
1409 #if MONO_TRACE
1410                         if (trace != null)
1411                                 trace.Write ("control", String.Format ("End UnloadRecursive {0} {1}", _userId, type_name));
1412 #endif
1413 #if NET_2_0
1414                         if (Adapter != null)
1415                                 Adapter.OnUnload (EventArgs.Empty);
1416                         else
1417 #endif
1418                                 OnUnload (EventArgs.Empty);
1419                         if (dispose)
1420                                 Dispose ();
1421                 }
1422
1423                 internal void PreRenderRecursiveInternal ()
1424                 {
1425                         bool visible;
1426
1427 #if NET_2_0
1428                         visible = Visible;
1429 #else
1430                         visible = (stateMask & VISIBLE) != 0;
1431 #endif
1432                         
1433                         if (visible) {
1434 #if NET_2_0
1435                                 SetMask (VISIBLE, true);
1436 #endif
1437                                 EnsureChildControls ();
1438 #if MONO_TRACE
1439                                 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1440                                 string type_name = null;
1441                                 if (trace != null) {
1442                                         type_name = GetType ().Name;
1443                                         trace.Write ("control", String.Format ("PreRenderRecursive {0} {1}", _userId, type_name));
1444                                 }
1445 #endif
1446 #if NET_2_0
1447                                 if (Adapter != null)
1448                                         Adapter.OnPreRender (EventArgs.Empty);
1449                                 else
1450 #endif
1451                                         OnPreRender (EventArgs.Empty);
1452                                 if (!HasControls ())
1453                                         return;
1454
1455                                 int len = _controls.Count;
1456                                 for (int i = 0; i < len; i++) {
1457                                         Control c = _controls [i];
1458                                         c.PreRenderRecursiveInternal ();
1459                                 }
1460 #if MONO_TRACE
1461                                 if (trace != null)
1462                                         trace.Write ("control", String.Format ("End PreRenderRecursive {0} {1}", _userId, type_name));
1463 #endif
1464                         }
1465 #if NET_2_0
1466                         else
1467                                 SetMask (VISIBLE, false);
1468 #endif
1469                         
1470                         stateMask |= PRERENDERED;
1471                 }
1472
1473                 internal void InitRecursive (Control namingContainer)
1474                 {
1475 #if MONO_TRACE
1476                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1477                         string type_name = null;
1478                         if (trace != null) {
1479                                 type_name = GetType ().Name;
1480                                 trace.Write ("control", String.Format ("InitRecursive {0} {1}", _userId, type_name));
1481                         }
1482 #endif
1483                         SetNamingContainer (namingContainer);
1484
1485                         if (HasControls ()) {
1486                                 if ((stateMask & IS_NAMING_CONTAINER) != 0)
1487                                         namingContainer = this;
1488
1489                                 int len = _controls.Count;
1490                                 for (int i = 0; i < len; i++) {
1491                                         Control c = _controls [i];
1492                                         c.InitRecursive (namingContainer);
1493                                 }
1494                         }
1495
1496                         stateMask |= INITING;
1497 #if NET_2_0
1498                         ApplyTheme ();
1499
1500                         if (Adapter != null)
1501                                 Adapter.OnInit (EventArgs.Empty);
1502                         else
1503 #endif
1504                                 OnInit (EventArgs.Empty);
1505 #if MONO_TRACE
1506                         if (trace != null)
1507                                 trace.Write ("control", String.Format ("End InitRecursive {0} {1}", _userId, type_name));
1508 #endif
1509                         TrackViewState ();
1510                         stateMask |= INITED;
1511                         stateMask &= ~INITING;
1512                 }
1513
1514                 internal object SaveViewStateRecursive ()
1515                 {
1516                         if (!EnableViewState)
1517                                 return null;
1518
1519 #if MONO_TRACE
1520                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1521                         string type_name = null;
1522                         if (trace != null) {
1523                                 type_name = GetType ().Name;
1524                                 trace.Write ("control", String.Format ("SaveViewStateRecursive {0} {1}", _userId, type_name));
1525                         }
1526 #endif
1527
1528                         ArrayList controlList = null;
1529                         ArrayList controlStates = null;
1530
1531                         int idx = -1;
1532                         if (HasControls ()) {
1533                                 int len = _controls.Count;
1534                                 for (int i = 0; i < len; i++) {
1535                                         Control ctrl = _controls [i];
1536                                         object ctrlState = ctrl.SaveViewStateRecursive ();
1537                                         idx++;
1538                                         if (ctrlState == null)
1539                                                 continue;
1540
1541                                         if (controlList == null) {
1542                                                 controlList = new ArrayList ();
1543                                                 controlStates = new ArrayList ();
1544                                         }
1545
1546                                         controlList.Add (idx);
1547                                         controlStates.Add (ctrlState);
1548                                 }
1549                         }
1550
1551                         object thisState = SaveViewState ();
1552                         if (thisState == null && controlList == null && controlStates == null) {
1553 #if MONO_TRACE
1554                                 if (trace != null) {
1555                                         trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved nothing", _userId, type_name));
1556                                         trace.SaveViewState (this, null);
1557                                 }
1558 #endif
1559                                 return null;
1560                         }
1561
1562 #if MONO_TRACE
1563                         if (trace != null) {
1564                                 trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved a Triplet", _userId, type_name));
1565                                 trace.SaveViewState (this, thisState);
1566                         }
1567 #endif
1568                         return new Triplet (thisState, controlList, controlStates);
1569                 }
1570
1571                 internal void LoadViewStateRecursive (object savedState)
1572                 {
1573                         if (!EnableViewState || savedState == null)
1574                                 return;
1575
1576 #if MONO_TRACE
1577                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1578                         string type_name = null;
1579                         if (trace != null) {
1580                                 type_name = GetType ().Name;
1581                                 trace.Write ("control", String.Format ("LoadViewStateRecursive {0} {1}", _userId, type_name));
1582                         }
1583 #endif
1584                         Triplet savedInfo = (Triplet) savedState;
1585                         LoadViewState (savedInfo.First);
1586
1587                         ArrayList controlList = savedInfo.Second as ArrayList;
1588                         if (controlList == null)
1589                                 return;
1590                         ArrayList controlStates = savedInfo.Third as ArrayList;
1591                         int nControls = controlList.Count;
1592                         for (int i = 0; i < nControls; i++) {
1593                                 int k = (int) controlList [i];
1594                                 if (k < Controls.Count && controlStates != null) {
1595                                         Control c = Controls [k];
1596                                         c.LoadViewStateRecursive (controlStates [i]);
1597                                 }
1598                                 else {
1599                                         if (pendingVS == null)
1600                                                 pendingVS = new Hashtable ();
1601
1602                                         pendingVS [k] = controlStates [i];
1603                                 }
1604                         }
1605
1606 #if MONO_TRACE
1607                         if (trace != null)
1608                                 trace.Write ("control", String.Format ("End LoadViewStateRecursive {0} {1}", _userId, type_name));
1609 #endif
1610                         stateMask |= VIEWSTATE_LOADED;
1611                 }
1612
1613 #if NET_2_0
1614                 internal ControlSkin controlSkin;
1615
1616                 internal void ApplyTheme ()
1617                 {
1618 #if MONO_TRACE
1619                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1620                         string type_name = null;
1621                         if (trace != null) {
1622                                 type_name = GetType ().Name;
1623                                 trace.Write ("control", String.Format ("ApplyThemeRecursive {0} {1}", _userId, type_name));
1624                         }
1625 #endif
1626                         if (Page.PageTheme != null && EnableTheming) {
1627                                 ControlSkin controlSkin = Page.PageTheme.GetControlSkin (GetType (), SkinID);
1628                                 if (controlSkin != null)
1629                                         controlSkin.ApplySkin (this);
1630                         }
1631
1632 #if MONO_TRACE
1633                         if (trace != null)
1634                                 trace.Write ("control", String.Format ("End ApplyThemeRecursive {0} {1}", _userId, type_name));
1635 #endif
1636                 }
1637 #endif
1638
1639                 internal bool AutoID {
1640                         get { return (stateMask & AUTOID) != 0; }
1641                         set {
1642                                 if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
1643                                         return;
1644
1645                                 SetMask (AUTOID, value);
1646                         }
1647                 }
1648
1649                 protected internal virtual void RemovedControl (Control control)
1650                 {
1651                         control.UnloadRecursive (false);
1652                         control._parent = null;
1653                         control._page = null;
1654                         control._namingContainer = null;
1655                         if ((control.stateMask & AUTOID_SET) != 0) {
1656                                 control._userId = null;
1657                                 control.SetMask (ID_SET, false);
1658                         }
1659                         control.NullifyUniqueID ();
1660                 }
1661                 
1662 #if NET_2_0
1663                 string skinId = string.Empty;
1664                 bool _enableTheming = true;
1665
1666                 [Browsable (false)]
1667                 [Themeable (false)]
1668                 [DefaultValue (true)]
1669                 public virtual bool EnableTheming {
1670                         get {
1671                                 if ((stateMask & ENABLE_THEMING) != 0)
1672                                         return _enableTheming;
1673
1674                                 if (_parent != null)
1675                                         return _parent.EnableTheming;
1676
1677                                 return true;
1678                         }
1679                         set {
1680                                 SetMask (ENABLE_THEMING, true);
1681                                 _enableTheming = value;
1682                         }
1683                 }
1684
1685                 [Browsable (false)]
1686                 [DefaultValue ("")]
1687                 [Filterable (false)]
1688                 public virtual string SkinID {
1689                         get { return skinId; }
1690                         set { skinId = value; }
1691                 }
1692
1693                 ControlBuilder IControlBuilderAccessor.ControlBuilder {
1694                         get { throw new NotImplementedException (); }
1695                 }
1696
1697                 IDictionary IControlDesignerAccessor.GetDesignModeState ()
1698                 {
1699                         throw new NotImplementedException ();
1700                 }
1701
1702                 void IControlDesignerAccessor.SetDesignModeState (IDictionary designData)
1703                 {
1704                         SetDesignModeState (designData);
1705                 }
1706
1707                 void IControlDesignerAccessor.SetOwnerControl (Control control)
1708                 {
1709                         throw new NotImplementedException ();
1710                 }
1711
1712                 IDictionary IControlDesignerAccessor.UserData {
1713                         get { throw new NotImplementedException (); }
1714                 }
1715
1716                 ExpressionBindingCollection expressionBindings;
1717
1718                 ExpressionBindingCollection IExpressionsAccessor.Expressions {
1719                         get {
1720                                 if (expressionBindings == null)
1721                                         expressionBindings = new ExpressionBindingCollection ();
1722                                 return expressionBindings;
1723                         }
1724                 }
1725
1726                 bool IExpressionsAccessor.HasExpressions {
1727                         get { return (expressionBindings != null && expressionBindings.Count > 0); }
1728                 }
1729
1730                 public virtual void Focus ()
1731                 {
1732                         Page.SetFocus (this);
1733                 }
1734
1735                 protected internal virtual void LoadControlState (object state)
1736                 {
1737                 }
1738
1739                 protected internal virtual object SaveControlState ()
1740                 {
1741                         return null;
1742                 }
1743
1744                 protected virtual void DataBind (bool raiseOnDataBinding)
1745                 {
1746                         bool foundDataItem = false;
1747
1748                         if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
1749                                 object o = DataBinder.GetDataItem (this, out foundDataItem);
1750                                 if (foundDataItem)
1751                                         Page.PushDataItemContext (o);
1752                         }
1753
1754                         try {
1755                                 if (raiseOnDataBinding)
1756                                         OnDataBinding (EventArgs.Empty);
1757                                 DataBindChildren ();
1758                         } finally {
1759                                 if (foundDataItem)
1760                                         Page.PopDataItemContext ();
1761                         }
1762                 }
1763
1764                 protected virtual IDictionary GetDesignModeState ()
1765                 {
1766                         throw new NotImplementedException ();
1767                 }
1768
1769                 protected virtual void SetDesignModeState (IDictionary data)
1770                 {
1771                         throw new NotImplementedException ();
1772                 }
1773 #endif
1774                 void IParserAccessor.AddParsedSubObject (object obj)
1775                 {
1776                         this.AddParsedSubObject (obj);
1777                 }
1778
1779                 DataBindingCollection IDataBindingsAccessor.DataBindings {
1780                         get {
1781                                 if (dataBindings == null) {
1782                                         dataBindings = new DataBindingCollection ();
1783                                 }
1784                                 return dataBindings;
1785                         }
1786                 }
1787
1788                 bool IDataBindingsAccessor.HasDataBindings {
1789                         get {
1790                                 if (dataBindings != null && dataBindings.Count > 0) {
1791                                         return true;
1792                                 }
1793                                 return false;
1794                         }
1795                 }
1796         }
1797 }