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