This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[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 //
9 // (C) Bob Smith
10 // (c) 2002,2003 Ximian, Inc. (http://www.ximian.com)
11 //
12
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System;
35 using System.Collections;
36 using System.ComponentModel;
37 using System.ComponentModel.Design;
38 using System.ComponentModel.Design.Serialization;
39 using System.Web;
40 using System.Web.Util;
41
42 namespace System.Web.UI
43 {
44         [DefaultProperty ("ID"), DesignerCategory ("Code"), ToolboxItemFilter ("System.Web.UI", ToolboxItemFilterType.Require)]
45         [ToolboxItem ("System.Web.UI.Design.WebControlToolboxItem, " + Consts.AssemblySystem_Design)]
46         [Designer ("System.Web.UI.Design.ControlDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
47         [DesignerSerializer ("Microsoft.VSDesigner.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
48         public class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor
49         {
50                 private static readonly object DataBindingEvent = new object();
51                 private static readonly object DisposedEvent = new object();
52                 private static readonly object InitEvent = new object();
53                 private static readonly object LoadEvent = new object();
54                 private static readonly object PreRenderEvent = new object();
55                 private static readonly object UnloadEvent = new object();
56                 private string uniqueID;
57                 private string _userId;
58                 private bool id_set;
59                 private ControlCollection _controls;
60                 private bool _enableViewState = true;
61                 private IDictionary _childViewStates;
62                 private bool _isNamingContainer;
63                 private Control _namingContainer;
64                 private Page _page;
65                 private Control _parent;
66                 private ISite _site;
67                 private bool _visible = true;
68                 private bool visibleChanged;
69                 private HttpContext _context;
70                 private bool _childControlsCreated;
71                 private StateBag _viewState;
72                 private bool _trackViewState;
73                 private EventHandlerList _events;
74                 private RenderMethod _renderMethodDelegate;
75                 private bool autoID = true;
76                 private bool creatingControls;
77                 private bool bindingContainer = true;
78                 private bool autoEventWireup = true;
79
80                 bool inited, initing;
81                 bool viewStateLoaded;
82                 bool loaded;
83                 bool prerendered;
84                 int defaultNumberID;
85  
86                 DataBindingCollection dataBindings;
87                 Hashtable pendingVS; // may hold unused viewstate data from child controls
88
89                 public Control()\r
90                 {\r
91                         if (this is INamingContainer) _isNamingContainer = true;\r
92                 }\r
93
94                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
95                 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]\r
96                 public Control BindingContainer\r
97                 {\r
98                         get {\r
99                                 Control container = NamingContainer;\r
100                                 if (!container.bindingContainer)\r
101                                         container = container.BindingContainer;\r
102                                 return container;\r
103                         }\r
104                 }\r
105                 
106                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
107                 [Browsable (false)]
108                 [WebSysDescription ("An Identification of the control that is rendered.")]\r
109                 public virtual string ClientID {\r
110                         get {\r
111                                 string client = UniqueID;\r
112 \r
113                                 if (client != null)\r
114                                         client = client.Replace (':', '_');\r
115 \r
116                                 return client;\r
117                         }\r
118                 }\r
119
120                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
121                 [Browsable (false)]
122                 [WebSysDescription ("The child controls of this control.")]\r
123                 public virtual ControlCollection Controls //DIT\r
124                 {\r
125                         get\r
126                         {\r
127                                 if (_controls == null) _controls = CreateControlCollection();\r
128                                 return _controls;\r
129                         }\r
130                 }
131
132                 [DefaultValue (true), WebCategory ("FIXME")]
133                 [WebSysDescription ("An Identification of the control that is rendered.")]\r
134                 public virtual bool EnableViewState //DIT\r
135                 {\r
136                         get\r
137                         {\r
138                                 return _enableViewState;\r
139                         }\r
140                         set\r
141                         {\r
142                                 _enableViewState = value;\r
143                         }\r
144                 }\r
145                 
146                 [MergableProperty (false), ParenthesizePropertyName (true)]
147                 [WebSysDescription ("The name of the control that is rendered.")]\r
148                 public virtual string ID {\r
149                         get {\r
150                                 return (id_set ? _userId : null);
151                         }\r
152                         \r
153                         set {\r
154                                 if (value == "")\r
155                                         value = null;\r
156 \r
157                                 id_set = true;
158                                 _userId = value;\r
159                                 NullifyUniqueID ();\r
160                         }\r
161                 }\r
162                 
163                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
164                 [Browsable (false)]
165                 [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]\r
166                 public virtual Control NamingContainer //DIT\r
167                 {\r
168                         get\r
169                         {\r
170                                 if (_namingContainer == null && _parent != null)\r
171                                 {\r
172                                         if (_parent._isNamingContainer == false)\r
173                                                 _namingContainer = _parent.NamingContainer;\r
174                                         else\r
175                                                 _namingContainer = _parent;\r
176                                 }\r
177                                 return _namingContainer;\r
178                         }\r
179                 }
180
181                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
182                 [Browsable (false)]
183                 [WebSysDescription ("The webpage that this control resides on.")]\r
184                 public virtual Page Page //DIT\r
185                 {\r
186                         get\r
187                         {\r
188                                 if (_page == null && _parent != null) _page = _parent.Page;\r
189                                 return _page;\r
190                         }\r
191                         set\r
192                         {\r
193                                 _page = value;\r
194                         }\r
195                 }
196
197                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
198                 [Browsable (false)]
199                 [WebSysDescription ("The parent control of this control.")]\r
200                 public virtual Control Parent //DIT\r
201                 {\r
202                         get\r
203                         {\r
204                                 return _parent;\r
205                         }\r
206                 }
207
208                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
209                 [EditorBrowsable (EditorBrowsableState.Advanced), Browsable (false)]
210                 [WebSysDescription ("The site this control is part of.")]\r
211                 public ISite Site //DIT\r
212                 {\r
213                         get\r
214                         {\r
215                                 return _site;\r
216                         }\r
217                         set\r
218                         {\r
219                                 _site = value;\r
220                         }\r
221                 }\r
222
223                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
224                 [Browsable (false)]
225                 [WebSysDescription ("A virtual directory containing the parent of the control.")]\r
226                 public virtual string TemplateSourceDirectory {\r
227                         get { return (_parent == null) ? String.Empty : _parent.TemplateSourceDirectory; }\r
228                 }\r
229
230                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
231                 [Browsable (false)]
232                 [WebSysDescription ("The unique ID of the control.")]\r
233                 public virtual string UniqueID {\r
234                         get {\r
235                                 if (uniqueID != null)\r
236                                         return uniqueID;\r
237 \r
238                                 if (_namingContainer == null) {\r
239                                         return _userId;\r
240                                 }\r
241 \r
242                                 if (_userId == null)\r
243                                         _userId = _namingContainer.GetDefaultName ();\r
244 \r
245                                 string prefix = _namingContainer.UniqueID;\r
246                                 if (_namingContainer == _page || prefix == null) {\r
247                                         uniqueID = _userId;\r
248                                         return uniqueID;\r
249                                 }\r
250 \r
251                                 uniqueID = prefix + ":" + _userId;\r
252                                 return uniqueID;\r
253                         }\r
254                 }
255
256                 [DefaultValue (true), Bindable (true), WebCategory ("FIXME")]
257                 [WebSysDescription ("Visiblity state of the control.")]
258                 public virtual bool Visible {
259                         get {
260                                 if (_visible == false)
261                                         return false;
262
263                                 if (_parent != null)
264                                         return _parent.Visible;
265
266                                 return true;
267                         }
268
269                         set {
270                                 if (value != _visible) {
271                                         if (IsTrackingViewState)
272                                                 visibleChanged = true;
273                                 }
274
275                                 _visible = value;
276                         }
277                 }
278
279                 protected bool ChildControlsCreated //DIT\r
280                 {\r
281                         get\r
282                         {\r
283                                 return _childControlsCreated;\r
284                         }\r
285                         set\r
286                         {\r
287                                 if (value == false && _childControlsCreated == true)\r
288                                         _controls.Clear();\r
289                                 _childControlsCreated = value;\r
290                         }\r
291                 }\r
292
293                 [Browsable (false)]
294                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
295                 protected virtual HttpContext Context //DIT\r
296                 {\r
297                         get\r
298                         {\r
299                                 HttpContext context;\r
300                                 if (_context != null)\r
301                                         return _context;\r
302                                 if (_parent == null)\r
303                                         return HttpContext.Current;\r
304                                 context = _parent.Context;\r
305                                 if (context != null)\r
306                                         return context;\r
307                                 return HttpContext.Current;\r
308                         }\r
309                 }\r
310                 protected EventHandlerList Events //DIT\r
311                 {\r
312                         get\r
313                         {\r
314                                 if (_events == null)\r
315                                 {\r
316                                         _events = new EventHandlerList();\r
317                                 }\r
318                                 return _events;\r
319                         }\r
320                 }\r
321                 protected bool HasChildViewState //DIT\r
322                 {\r
323                         get\r
324                         {\r
325                                 if (_childViewStates == null) return false;\r
326                                 return true;\r
327                         }\r
328                 }\r
329                 protected bool IsTrackingViewState //DIT\r
330                 {\r
331                         get\r
332                         {\r
333                                 return _trackViewState;\r
334                         }\r
335                 }\r
336
337                 [Browsable (false)]
338                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
339                 [WebSysDescription ("ViewState")]
340                 protected virtual StateBag ViewState\r
341                 {\r
342                         get\r
343                         {\r
344                                 if(_viewState == null)\r
345                                         _viewState = new StateBag (ViewStateIgnoresCase);\r
346 \r
347                                 if (IsTrackingViewState)\r
348                                         _viewState.TrackViewState ();\r
349 \r
350                                 return _viewState;\r
351                         }\r
352                 }\r
353 \r
354                 [Browsable (false)]
355                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
356                 protected virtual bool ViewStateIgnoresCase\r
357                 {\r
358                         get {\r
359                                 return false;\r
360                         }\r
361                 }\r
362 \r
363                 internal bool AutoEventWireup {\r
364                         get { return autoEventWireup; }\r
365                         set { autoEventWireup = value; }\r
366                 }\r
367 \r
368                 internal void SetBindingContainer (bool isBC)\r
369                 {\r
370                         bindingContainer = isBC;\r
371                 }\r
372                 \r
373                 internal void ResetChildNames ()\r
374                 {\r
375                         defaultNumberID = 0;\r
376                 }\r
377                 \r
378                 string GetDefaultName ()\r
379                 {\r
380                         return "_ctrl" + defaultNumberID++;\r
381                 }\r
382                 \r
383                 void NullifyUniqueID ()\r
384                 {\r
385                         uniqueID = null;\r
386                         if (_controls == null)\r
387                                 return;\r
388 \r
389                         foreach (Control c in _controls)\r
390                                 c.NullifyUniqueID ();\r
391                 }\r
392                 \r
393                 protected internal virtual void AddedControl (Control control, int index)\r
394                 {\r
395                         /* Ensure the control don't have more than 1 parent */
396                         if (control._parent != null)
397                                 control._parent.Controls.Remove (control);
398
399                         control._parent = this;
400                         control._page = _page;
401                         Control nc = _isNamingContainer ? this : NamingContainer;
402
403                         if (nc != null) {
404                                 control._namingContainer = nc;
405                                 if (control.AutoID == true && control._userId == null)
406                                         control._userId =  nc.GetDefaultName () + "a";
407                         }
408
409                         if (initing || inited)
410                                 control.InitRecursive (nc);
411
412                         if (viewStateLoaded || loaded) {
413                                 if (pendingVS != null) {
414                                         object vs = pendingVS [index];
415                                         if (vs != null) {
416                                                 pendingVS.Remove (index);
417                                                 if (pendingVS.Count == 0)
418                                                         pendingVS = null;
419                                         
420                                                 control.LoadViewStateRecursive (vs);
421                                         }
422                                 }
423                         }
424
425                         if (loaded)
426                                 control.LoadRecursive ();
427                         
428                         if (prerendered)
429                                 control.PreRenderRecursiveInternal ();
430                 }
431
432                 protected virtual void AddParsedSubObject(object obj) //DIT\r
433                 {\r
434                         WebTrace.PushContext ("Control.AddParsedSubobject ()");\r
435                         Control c = obj as Control;\r
436                         WebTrace.WriteLine ("Start: {0} -> {1}", obj, (c != null) ? c.ID : String.Empty);\r
437                         if (c != null) Controls.Add(c);\r
438                         WebTrace.WriteLine ("End");\r
439                         WebTrace.PopContext ();\r
440                 }\r
441
442                 protected void BuildProfileTree(string parentId, bool calcViewState)\r
443                 {\r
444                         //TODO\r
445                 }\r
446
447                 protected void ClearChildViewState ()
448                 {
449                         pendingVS = null;
450                 }
451
452                 protected virtual void CreateChildControls() {} //DIT\r
453                 protected virtual ControlCollection CreateControlCollection() //DIT\r
454                 {\r
455                         return new ControlCollection(this);\r
456                 }\r
457 \r
458                 protected virtual void EnsureChildControls () //DIT\r
459                 {\r
460                         if (ChildControlsCreated == false && !creatingControls) {\r
461                                 creatingControls = true;\r
462                                 CreateChildControls();\r
463                                 ChildControlsCreated = true;\r
464                                 creatingControls = false;\r
465                         }\r
466                 }
467
468                 protected bool IsLiteralContent()
469                 {
470                         if (_controls != null) 
471                                 if (_controls.Count == 1)
472                                         if (_controls[0] is LiteralControl)
473                                                 return true;
474                         return false;
475                 }\r
476 \r
477                 public virtual Control FindControl (string id)\r
478                 {\r
479                         return FindControl (id, 0);\r
480                 }\r
481 \r
482                 Control LookForControlByName (string id)\r
483                 {\r
484                         if (!HasChildren)\r
485                                 return null;\r
486 \r
487                         foreach (Control c in _controls) {\r
488                                 if (String.Compare (id, c._userId, true) == 0)\r
489                                         return c;\r
490 \r
491                                 if (!c._isNamingContainer && c.HasChildren) {\r
492                                         Control child = c.LookForControlByName (id);\r
493                                         if (child != null)\r
494                                                 return child;\r
495                                 }\r
496                         }\r
497 \r
498                         return null;\r
499                 }\r
500                 \r
501                 protected virtual Control FindControl (string id, int pathOffset)\r
502                 {\r
503                         EnsureChildControls ();\r
504                         if (_controls == null)\r
505                                 return null;\r
506 \r
507                         Control namingContainer = null;\r
508                         if (!_isNamingContainer) {\r
509                                 namingContainer = NamingContainer;\r
510                                 if (namingContainer == null)\r
511                                         return null;\r
512 \r
513                                 return namingContainer.FindControl (id, pathOffset);\r
514                         }\r
515 \r
516                         int colon = id.IndexOf (':', pathOffset);\r
517                         if (colon == -1)\r
518                                 return LookForControlByName (id.Substring (pathOffset));\r
519                         \r
520                         string idfound = id.Substring (pathOffset, colon - pathOffset);\r
521                         namingContainer = LookForControlByName (idfound);\r
522                         if (namingContainer == null)\r
523                                 return null;\r
524 \r
525                         return namingContainer.FindControl (id, colon + 1);\r
526                 }
527
528                 protected virtual void LoadViewState(object savedState)
529                 {
530                         if (savedState != null) {
531                                 ViewState.LoadViewState (savedState);
532                                 object o = ViewState ["Visible"];
533                                 if (o != null) {
534                                         _visible = (bool) o;
535                                         visibleChanged = true;
536                                 }
537                         }
538                 }
539
540                 [MonoTODO("Secure?")]\r
541                 protected string MapPathSecure(string virtualPath)\r
542                 {\r
543                         string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);\r
544                         return Context.Request.MapPath (combined);\r
545                 }\r
546 \r
547                 protected virtual bool OnBubbleEvent(object source, EventArgs args) //DIT\r
548                 {\r
549                         return false;\r
550                 }\r
551                 protected virtual void OnDataBinding(EventArgs e) //DIT\r
552                 {\r
553                         if (_events != null)\r
554                         {\r
555                                 EventHandler eh = (EventHandler)(_events[DataBindingEvent]);\r
556                                 if (eh != null) eh(this, e);\r
557                         }\r
558                 }\r
559                 protected virtual void OnInit(EventArgs e) //DIT\r
560                 {\r
561                         if (_events != null)\r
562                         {\r
563                                 EventHandler eh = (EventHandler)(_events[InitEvent]);\r
564                                 if (eh != null) eh(this, e);\r
565                         }\r
566                 }\r
567                 protected virtual void OnLoad(EventArgs e) //DIT\r
568                 {\r
569                         if (_events != null)\r
570                         {\r
571                                 EventHandler eh = (EventHandler)(_events[LoadEvent]);\r
572                                 if (eh != null) eh(this, e);\r
573                         }\r
574                 }\r
575                 protected virtual void OnPreRender(EventArgs e) //DIT\r
576                 {\r
577                         if (_events != null)\r
578                         {\r
579                                 EventHandler eh = (EventHandler)(_events[PreRenderEvent]);\r
580                                 if (eh != null) eh(this, e);\r
581                         }\r
582                 }\r
583                 protected virtual void OnUnload(EventArgs e) //DIT\r
584                 {\r
585                         if (_events != null)\r
586                         {\r
587                                 EventHandler eh = (EventHandler)(_events[UnloadEvent]);\r
588                                 if (eh != null) eh(this, e);\r
589                         }\r
590                 }\r
591                 \r
592                 protected void RaiseBubbleEvent(object source, EventArgs args)\r
593                 {\r
594                         Control c = Parent;\r
595                         while (c != null) {\r
596                                 if (c.OnBubbleEvent (source, args))\r
597                                         break;\r
598                                 c = c.Parent;\r
599                         }\r
600                 }\r
601 \r
602                 protected virtual void Render(HtmlTextWriter writer) //DIT\r
603                 {\r
604                         RenderChildren(writer);\r
605                 }\r
606 \r
607                 protected virtual void RenderChildren(HtmlTextWriter writer) //DIT\r
608                 {\r
609                         if (_renderMethodDelegate != null)\r
610                                 _renderMethodDelegate(writer, this);\r
611                         else if (_controls != null)\r
612                                 foreach (Control c in _controls)\r
613                                         c.RenderControl(writer);\r
614                 }\r
615
616                 protected virtual object SaveViewState ()
617                 {
618                         if (visibleChanged) {
619                                 ViewState ["Visible"] = Visible;
620                         } else if (_viewState == null) {
621                                 return null;
622                         }
623
624                         return _viewState.SaveViewState ();
625                 }
626
627                 protected virtual void TrackViewState()\r
628                 {\r
629                         if (_viewState != null)\r
630                                 _viewState.TrackViewState ();\r
631                         _trackViewState = true;\r
632                 }\r
633                 \r
634                 public virtual void Dispose()\r
635                 {\r
636                         if (_events != null)\r
637                         {\r
638                                 EventHandler eh = (EventHandler) _events [DisposedEvent];\r
639                                 if (eh != null)\r
640                                         eh(this, EventArgs.Empty);\r
641                         }\r
642                 }\r
643 \r
644                 internal bool HasChildren\r
645                 {\r
646                         get { return (_controls != null && _controls.Count > 0); }\r
647                 }\r
648
649                 [WebCategory ("FIXME")]
650                 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]\r
651                 public event EventHandler DataBinding //DIT\r
652                 {\r
653                         add\r
654                         {\r
655                                 Events.AddHandler(DataBindingEvent, value);\r
656                         }\r
657                         remove\r
658                         {\r
659                                 Events.RemoveHandler(DataBindingEvent, value);\r
660                         }\r
661                 }
662
663                 [WebSysDescription ("Raised when the contol is disposed.")]\r
664                 public event EventHandler Disposed //DIT\r
665                 {\r
666                         add\r
667                         {\r
668                                 Events.AddHandler(DisposedEvent, value);\r
669                         }\r
670                         remove\r
671                         {\r
672                                 Events.RemoveHandler(DisposedEvent, value);\r
673                         }\r
674                 }
675
676                 [WebSysDescription ("Raised when the page containing the control is initialized.")]\r
677                 public event EventHandler Init //DIT\r
678                 {\r
679                         add\r
680                         {\r
681                                 Events.AddHandler(InitEvent, value);\r
682                         }\r
683                         remove\r
684                         {\r
685                                 Events.RemoveHandler(InitEvent, value);\r
686                         }\r
687                 }
688
689                 [WebSysDescription ("Raised after the page containing the control has been loaded.")]\r
690                 public event EventHandler Load //DIT\r
691                 {\r
692                         add\r
693                         {\r
694                                 Events.AddHandler(LoadEvent, value);\r
695                         }\r
696                         remove\r
697                         {\r
698                                 Events.RemoveHandler(LoadEvent, value);\r
699                         }\r
700                 }
701
702                 [WebSysDescription ("Raised before the page containing the control is rendered.")]\r
703                 public event EventHandler PreRender //DIT\r
704                 {\r
705                         add\r
706                         {\r
707                                 Events.AddHandler(PreRenderEvent, value);\r
708                         }\r
709                         remove\r
710                         {\r
711                                 Events.RemoveHandler(PreRenderEvent, value);\r
712                         }\r
713                 }
714
715                 [WebSysDescription ("Raised when the page containing the control is unloaded.")]\r
716                 public event EventHandler Unload //DIT\r
717                 {\r
718                         add\r
719                         {\r
720                                 Events.AddHandler(UnloadEvent, value);\r
721                         }\r
722                         remove\r
723                         {\r
724                                 Events.RemoveHandler(UnloadEvent, value);\r
725                         }\r
726                 }\r
727 \r
728                 public virtual void DataBind() //DIT\r
729                 {
730                         #if NET_2_0
731                         bool foundDataItem = false;
732                         
733                         if (_isNamingContainer && Page != null) {
734                                 object o = DataBinder.GetDataItem (this, out foundDataItem);
735                                 if (foundDataItem)
736                                         Page.PushDataItemContext (o);
737                         }
738                         
739                         try {
740                         #endif
741                                 
742                                 OnDataBinding (EventArgs.Empty);
743                                 DataBindChildren();
744                         
745                         #if NET_2_0
746                         } finally {
747                                 if (foundDataItem)
748                                         Page.PopDataItemContext ();
749                         }
750                         #endif
751                 }
752                 
753                 #if NET_2_0
754                 protected virtual
755                 #endif
756                 
757                 void DataBindChildren ()
758                 {
759                         if (_controls == null)
760                                 return;
761                         
762                         foreach (Control c in _controls)
763                                 c.DataBind();
764                 }
765
766
767                 public virtual bool HasControls ()
768                 {
769                         return (_controls != null && _controls.Count > 0);
770                 }
771
772                 public void RenderControl(HtmlTextWriter writer)
773                 {
774                         if (_visible)
775                                 Render(writer);
776                 }
777
778                 public string ResolveUrl(string relativeUrl)
779                 {
780                         if (relativeUrl == null)
781                                 throw new ArgumentNullException ("relativeUrl");
782
783                         if (relativeUrl == "")
784                                 return "";
785
786                         if (relativeUrl [0] == '#')
787                                 return relativeUrl;
788                         
789                         string ts = TemplateSourceDirectory;
790                         if (ts == "" || !UrlUtils.IsRelativeUrl (relativeUrl))
791                                 return relativeUrl;
792
793                         if (relativeUrl.IndexOf ('/') == -1 && relativeUrl [0] != '.' && relativeUrl != "..")
794                                 return relativeUrl;
795
796                         HttpResponse resp = Context.Response;
797                         return resp.ApplyAppPathModifier (UrlUtils.Combine (ts, relativeUrl));
798                 }
799
800                 [EditorBrowsable (EditorBrowsableState.Advanced)]\r
801                 public void SetRenderMethodDelegate(RenderMethod renderMethod) //DIT\r
802                 {\r
803                         _renderMethodDelegate = renderMethod;\r
804                 }\r
805 \r
806                 internal void LoadRecursive()\r
807                 {\r
808                         OnLoad (EventArgs.Empty);\r
809                         if (_controls != null) {\r
810                                 foreach (Control c in _controls)\r
811                                         c.LoadRecursive ();\r
812                         }\r
813                         loaded = true;\r
814                 }\r
815 \r
816                 internal void UnloadRecursive(Boolean dispose)\r
817                 {\r
818                         if (_controls != null) {\r
819                                 foreach (Control c in _controls)\r
820                                         c.UnloadRecursive (dispose);\r
821                         }\r
822 \r
823                         OnUnload (EventArgs.Empty);\r
824                         if (dispose)\r
825                                 Dispose();\r
826                 }\r
827
828                 internal void PreRenderRecursiveInternal()
829                 {
830                         if (_visible) {
831                                 EnsureChildControls ();
832                                 OnPreRender (EventArgs.Empty);
833                                 if (_controls == null)
834                                         return;
835
836                                 foreach (Control c in _controls)
837                                         c.PreRenderRecursiveInternal ();
838                         }
839                         prerendered = true;
840                 }
841
842                 internal void InitRecursive(Control namingContainer)\r
843                 {\r
844                         if (_controls != null) {\r
845                                 if (_isNamingContainer)\r
846                                         namingContainer = this;\r
847 \r
848                                 if (namingContainer != null && \r
849                                     namingContainer._userId == null &&\r
850                                     namingContainer.autoID)\r
851                                         namingContainer._userId = namingContainer.GetDefaultName () + "b";\r
852 \r
853                                 foreach (Control c in _controls) {\r
854                                         c._page = Page;\r
855                                         c._namingContainer = namingContainer;\r
856                                         if (namingContainer != null && c._userId == null && c.autoID)\r
857                                                 c._userId = namingContainer.GetDefaultName () + "c";\r
858 \r
859                                         c.InitRecursive (namingContainer);\r
860                                 }\r
861                         }\r
862 \r
863                         initing = true;
864                         OnInit (EventArgs.Empty);\r
865                         TrackViewState ();\r
866                         inited = true;\r
867                         initing = false;
868                 }\r
869
870                 internal object SaveViewStateRecursive ()
871                 {
872                         if (!EnableViewState)
873                                 return null;
874
875                         ArrayList controlList = null;
876                         ArrayList controlStates = null;
877
878                         int idx = -1;
879                         foreach (Control ctrl in Controls) {
880                                 object ctrlState = ctrl.SaveViewStateRecursive ();
881                                 idx++;
882                                 if (ctrlState == null)
883                                         continue;
884
885                                 if (controlList == null) {
886                                         controlList = new ArrayList ();
887                                         controlStates = new ArrayList ();
888                                 }
889
890                                 controlList.Add (idx);
891                                 controlStates.Add (ctrlState);
892                         }
893
894                         object thisState = SaveViewState ();
895                         if (thisState == null && controlList == null && controlStates == null)
896                                 return null;
897
898                         return new Triplet (thisState, controlList, controlStates);
899                 }
900                 
901                 internal void LoadViewStateRecursive (object savedState)
902                 {
903                         if (!EnableViewState || savedState == null)
904                                 return;
905
906                         Triplet savedInfo = (Triplet) savedState;
907                         LoadViewState (savedInfo.First);
908
909                         ArrayList controlList = savedInfo.Second as ArrayList;
910                         if (controlList == null)
911                                 return;
912                         ArrayList controlStates = savedInfo.Third as ArrayList;
913                         int nControls = controlList.Count;
914                         for (int i = 0; i < nControls; i++) {
915                                 int k = (int) controlList [i];
916                                 if (k < Controls.Count && controlStates != null) {
917                                         Control c = Controls [k];
918                                         c.LoadViewStateRecursive (controlStates [i]);
919                                 } else {
920                                         if (pendingVS == null)
921                                                 pendingVS = new Hashtable ();
922
923                                         pendingVS [k] = controlStates [i];
924                                 }
925                         }
926
927                         viewStateLoaded = true;
928                 }
929                 
930                 void IParserAccessor.AddParsedSubObject(object obj)\r
931                 {\r
932                         AddParsedSubObject(obj);\r
933                 }\r
934                 \r
935                 DataBindingCollection IDataBindingsAccessor.DataBindings\r
936                 {\r
937                         get\r
938                         {\r
939                                 if(dataBindings == null)\r
940                                         dataBindings = new DataBindingCollection();\r
941                                 return dataBindings;\r
942                         }\r
943                 }\r
944                 \r
945                 bool IDataBindingsAccessor.HasDataBindings\r
946                 {\r
947                         get\r
948                         {\r
949                                 return (dataBindings!=null && dataBindings.Count>0);\r
950                         }\r
951                 }\r
952                 \r
953                 internal bool AutoID\r
954                 {\r
955                         get { return autoID; }\r
956                         set { \r
957                                 if (value == false && _isNamingContainer)\r
958                                         return;\r
959 \r
960                                 autoID = value;\r
961                         }\r
962                 }\r
963 \r
964                 internal void PreventAutoID()\r
965                 {\r
966                         AutoID = false;\r
967                 }\r
968                 \r
969                 protected internal virtual void RemovedControl (Control control)\r
970                 {\r
971                         control.UnloadRecursive (false);\r
972                         control._parent = null;\r
973                         control._page = null;\r
974                         control._namingContainer = null;\r
975                 }\r
976 \r
977                 #if NET_2_0
978                 protected string GetWebResourceUrl (string resourceName)
979                 {
980                         return Page.GetWebResourceUrl (GetType(), resourceName); 
981                 } 
982
983                 #endif\r
984         }\r
985 }\r