2006-02-07 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI / Control.cs
1 //
2 // System.Web.UI.Control.cs
3 //
4 // Authors:
5 //   Bob Smith <bob@thestuff.net>
6 //   Gonzalo Paniagua Javier (gonzalo@ximian.com
7 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 //   Sanjay Gupta (gsanjay@novell.com)
9 //
10 // (C) Bob Smith
11 // (c) 2002,2003 Ximian, Inc. (http://www.ximian.com)
12 // (C) 2004 Novell, Inc. (http://www.novell.com)
13 //
14
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35
36 // This will provide extra information when trace is enabled. Might be too verbose.
37 #define MONO_TRACE
38
39 using System.Collections;
40 using System.ComponentModel;
41 using System.ComponentModel.Design;
42 using System.ComponentModel.Design.Serialization;
43 using System.Security.Permissions;
44 using System.Web;
45 using System.Web.Util;
46 #if NET_2_0
47 using System.Web.UI.Adapters;
48 using System.IO;
49 #endif
50
51 namespace System.Web.UI
52 {
53         // CAS
54         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
55         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
56         // attributes
57         [DefaultProperty ("ID"), DesignerCategory ("Code"), ToolboxItemFilter ("System.Web.UI", ToolboxItemFilterType.Require)]
58         [ToolboxItem ("System.Web.UI.Design.WebControlToolboxItem, " + Consts.AssemblySystem_Design)]
59         [Designer ("System.Web.UI.Design.ControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
60 #if NET_2_0
61         [DesignerSerializer ("Microsoft.VisualStudio.Web.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VisualStudio_Web,
62                                 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
63         [Bindable (true)]
64         [Themeable (false)]
65 #else
66         [DesignerSerializer ("Microsoft.VSDesigner.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VSDesigner,
67                                 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
68 #endif          
69         public class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor
70 #if NET_2_0
71         , IUrlResolutionService, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor
72 #endif
73         {
74                 static readonly object DataBindingEvent = new object();
75                 static readonly object DisposedEvent = new object();
76                 static readonly object InitEvent = new object();
77                 static readonly object LoadEvent = new object();
78                 static readonly object PreRenderEvent = new object();
79                 static readonly object UnloadEvent = new object();
80                 static string[] defaultNameArray;
81                 /* */
82                 int event_mask;
83                 const int databinding_mask = 1;
84                 const int disposed_mask = 1 << 1;
85                 const int init_mask = 1 << 2;
86                 const int load_mask = 1 << 3;
87                 const int prerender_mask = 1 << 4;
88                 const int unload_mask = 1 << 5;
89                 /* */
90
91                 string uniqueID;
92                 string _userId;
93                 TemplateControl _templateControl;
94                 ControlCollection _controls;
95                 Control _namingContainer;
96                 Page _page;
97                 Control _parent;
98                 ISite _site;
99                 HttpContext _context;
100                 StateBag _viewState;
101                 EventHandlerList _events;
102                 RenderMethod _renderMethodDelegate;
103                 int defaultNumberID;
104  
105                 DataBindingCollection dataBindings;
106                 Hashtable pendingVS; // may hold unused viewstate data from child controls
107                 
108
109                 /*************/
110                 int stateMask;
111                 const int ENABLE_VIEWSTATE      = 1;
112                 const int VISIBLE               = 1 << 1;
113                 const int AUTOID                = 1 << 2;
114                 const int CREATING_CONTROLS     = 1 << 3;
115                 const int BINDING_CONTAINER     = 1 << 4;
116                 const int AUTO_EVENT_WIREUP     = 1 << 5;
117                 const int IS_NAMING_CONTAINER   = 1 << 6;
118                 const int VISIBLE_CHANGED       = 1 << 7;
119                 const int TRACK_VIEWSTATE       = 1 << 8;
120                 const int CHILD_CONTROLS_CREATED = 1 << 9;
121                 const int ID_SET                = 1 << 10;
122                 const int INITED                = 1 << 11;
123                 const int INITING               = 1 << 12;
124                 const int VIEWSTATE_LOADED      = 1 << 13;
125                 const int LOADED                = 1 << 14;
126                 const int PRERENDERED           = 1 << 15;
127 #if NET_2_0
128                 const int ENABLE_THEMING        = 1 << 16;
129 #endif
130                 /*************/
131                 
132                 static Control ()
133                 {
134                         defaultNameArray = new string [100];
135                         for (int i = 0 ; i < 100 ; i++)
136                                 defaultNameArray [i] = "_ctl" + i;
137                 }
138
139                 public Control()
140                 {
141                         stateMask = ENABLE_VIEWSTATE | VISIBLE | AUTOID | BINDING_CONTAINER | AUTO_EVENT_WIREUP;
142                         if (this is INamingContainer)
143                                 stateMask |= IS_NAMING_CONTAINER;
144                 }
145
146 #if NET_2_0
147                 [MonoTODO]
148                 protected ControlAdapter Adapter 
149                 {
150                         get {
151                                 // for the time being, fool the
152                                 // Control machinery into thinking we
153                                 // don't have an Adapter.  This will
154                                 // allow us to write all the rest of
155                                 // the Adapter handling code without
156                                 // having to worry about *having*
157                                 // adapters.
158                                 return null;
159                         }
160                 }
161
162                 [EditorBrowsable (EditorBrowsableState.Advanced)]
163                 [Browsable (false)]
164                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
165                 public string AppRelativeTemplateSourceDirectory 
166                 {
167                         get {
168                                 throw new NotImplementedException ();
169                         }
170                         [EditorBrowsable (EditorBrowsableState.Never)]
171                         set {
172                                 throw new NotImplementedException ();
173                         }
174                 }
175                 
176 #endif          
177
178                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
179                 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
180                 public Control BindingContainer {
181                         get {
182                                 Control container = NamingContainer;
183                                 if ((container.stateMask & BINDING_CONTAINER) == 0)
184                                         container = container.BindingContainer;
185                                 return container;
186                         }
187                 }
188
189                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
190                 [Browsable (false)]
191                 [WebSysDescription ("An Identification of the control that is rendered.")]
192                 public virtual string ClientID {
193                         get {
194                                 string client = UniqueID;
195
196                                 if (client != null)
197                                         client = client.Replace (':', '_');
198
199                                 return client;
200                         }
201                 }
202
203 #if NET_2_0
204                 protected char ClientIDSeparator 
205                 {
206                         get {
207                                 throw new NotImplementedException ();
208                         }
209                 }
210 #endif          
211
212                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
213                 [Browsable (false)]
214                 [WebSysDescription ("The child controls of this control.")]
215                 public virtual ControlCollection Controls //DIT
216                 {
217                         get
218                         {
219                                 if (_controls == null) _controls = CreateControlCollection();
220                                 return _controls;
221                         }
222                 }
223
224 #if NET_2_0
225                 protected internal bool DesignMode 
226                 {
227                         get {
228                                 throw new NotImplementedException ();
229                         }
230                 }
231 #endif          
232
233                 [DefaultValue (true), WebCategory ("Behavior")]
234                 [WebSysDescription ("An Identification of the control that is rendered.")]
235 #if NET_2_0
236                 [Themeable (false)]
237 #endif                
238                 public virtual bool EnableViewState {
239                         get { return ((stateMask & ENABLE_VIEWSTATE) != 0); }
240                         set { SetMask (ENABLE_VIEWSTATE, value); }
241                 }
242                 
243                 [MergableProperty (false), ParenthesizePropertyName (true)]
244                 [WebSysDescription ("The name of the control that is rendered.")]
245 #if NET_2_0
246                 [Filterable (false), Themeable (false)]
247 #endif                
248
249                 public virtual string ID {
250                         get {
251                                 return (((stateMask & ID_SET) != 0) ? _userId : null);
252                         }
253                         
254                         set {
255                                 if (value == "")
256                                         value = null;
257
258                                 stateMask |= ID_SET;
259                                 _userId = value;
260                                 NullifyUniqueID ();
261                         }
262                 }
263
264 #if NET_2_0
265                 protected char IdSeparator 
266                 {
267                         get {
268                                 throw new NotImplementedException ();
269                         }
270                 }
271
272                 protected internal bool IsChildControlStateCleared 
273                 {
274                         get {
275                                 throw new NotImplementedException ();
276                         }
277                 }
278
279                 protected internal bool IsViewStateEnabled 
280                 {
281                         get {
282                                 throw new NotImplementedException ();
283                         }
284                 }
285
286                 protected bool LoadViewStateByID 
287                 {
288                         get {
289                                 throw new NotImplementedException ();
290                         }
291                 }
292 #endif          
293                 
294                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
295                 [Browsable (false)]
296                 [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]
297                 public virtual Control NamingContainer {
298                         get {
299                                 if (_namingContainer == null && _parent != null) {
300                                         if ((_parent.stateMask & IS_NAMING_CONTAINER) == 0)
301                                                 _namingContainer = _parent.NamingContainer;
302                                         else
303                                                 _namingContainer = _parent;
304                                 }
305
306                                 return _namingContainer;
307                         }
308                 }
309
310                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
311                 [Browsable (false)]
312                 [WebSysDescription ("The webpage that this control resides on.")]
313 #if NET_2_0
314                 [Bindable (false)]
315 #endif                
316                 public virtual Page Page //DIT
317                 {
318                         get
319                         {
320                                 if (_page == null && _parent != null) _page = _parent.Page;
321                                 return _page;
322                         }
323                         set
324                         {
325                                 _page = value;
326                         }
327                 }
328
329                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
330                 [Browsable (false)]
331                 [WebSysDescription ("The parent control of this control.")]
332                 public virtual Control Parent //DIT
333                 {
334                         get
335                         {
336                                 return _parent;
337                         }
338                 }
339
340                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
341                 [EditorBrowsable (EditorBrowsableState.Advanced), Browsable (false)]
342                 [WebSysDescription ("The site this control is part of.")]
343                 public ISite Site //DIT
344                 {
345                         get
346                         {
347                                 return _site;
348                         }
349                         set
350                         {
351                                 _site = value;
352                         }
353                 }
354
355 #if NET_2_0
356                 [Browsable (false)]
357                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
358                 public TemplateControl TemplateControl 
359                 {
360                         get {
361                                 return _templateControl;
362                         }
363                         [EditorBrowsable (EditorBrowsableState.Never)]
364                         set {
365                                 _templateControl = value;
366                         }
367                 }
368 #endif          
369
370                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
371                 [Browsable (false)]
372                 [WebSysDescription ("A virtual directory containing the parent of the control.")]
373                 public virtual string TemplateSourceDirectory {
374                         get { return (_parent == null) ? String.Empty : _parent.TemplateSourceDirectory; }
375                 }
376
377                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
378                 [Browsable (false)]
379                 [WebSysDescription ("The unique ID of the control.")]
380                 public virtual string UniqueID {
381                         get {
382                                 if (uniqueID != null)
383                                         return uniqueID;
384
385                                 if (_namingContainer == null) {
386                                         if ((stateMask & IS_NAMING_CONTAINER) == 0)
387                                                 _namingContainer = NamingContainer;
388                                         if (_namingContainer == null)
389                                                 return _userId;
390                                 }
391
392                                 if (_userId == null)
393                                         _userId = _namingContainer.GetDefaultName ();
394
395                                 string prefix = _namingContainer.UniqueID;
396                                 if (_namingContainer == _page || prefix == null) {
397                                         uniqueID = _userId;
398                                         return uniqueID;
399                                 }
400
401                                 uniqueID = prefix + ":" + _userId;
402                                 return uniqueID;
403                         }
404                 }
405
406                 void SetMask (int m, bool val)
407                 {
408                         if (val)
409                                 stateMask |= m;
410                         else
411                                 stateMask &= ~m;
412                 }
413                 
414                 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
415                 [WebSysDescription ("Visiblity state of the control.")]
416                 public virtual bool Visible {
417                         get {
418                                 if ((stateMask & VISIBLE) == 0)
419                                         return false;
420
421                                 if (_parent != null)
422                                         return _parent.Visible;
423
424                                 return true;
425                         }
426
427                         set {
428                                 if ((value && (stateMask & VISIBLE) == 0) ||
429                                     (!value && (stateMask & VISIBLE) != 0)) {
430                                         if (IsTrackingViewState)
431                                                 stateMask |= VISIBLE_CHANGED;
432                                 }
433
434                                 SetMask (VISIBLE, value);
435                         }
436                 }
437
438                 protected bool ChildControlsCreated {
439                         get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
440                         set {
441                                 if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
442                                         if (_controls != null)
443                                                 _controls.Clear();
444                                 }
445
446                                 SetMask (CHILD_CONTROLS_CREATED, value);
447                         }
448                 }
449
450                 [Browsable (false)]
451                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
452                 protected virtual HttpContext Context //DIT
453                 {
454                         get
455                         {
456                                 HttpContext context;
457                                 if (_context != null)
458                                         return _context;
459                                 if (_parent == null)
460                                         return HttpContext.Current;
461                                 context = _parent.Context;
462                                 if (context != null)
463                                         return context;
464                                 return HttpContext.Current;
465                         }
466                 }
467
468                 protected EventHandlerList Events {
469                         get {
470                                 if (_events == null)
471                                         _events = new EventHandlerList ();
472                                 return _events;
473                         }
474                 }
475
476                 protected bool HasChildViewState {
477                         get {
478                                 return (pendingVS != null && pendingVS.Count > 0);
479                         }
480                 }
481
482                 protected bool IsTrackingViewState {
483                         get { return ((stateMask & TRACK_VIEWSTATE) != 0); }
484                 }
485
486                 [Browsable (false)]
487                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
488                 [WebSysDescription ("ViewState")]
489                 protected virtual StateBag ViewState
490                 {
491                         get
492                         {
493                                 if(_viewState == null)
494                                         _viewState = new StateBag (ViewStateIgnoresCase);
495
496                                 if (IsTrackingViewState)
497                                         _viewState.TrackViewState ();
498
499                                 return _viewState;
500                         }
501                 }
502
503                 [Browsable (false)]
504                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
505                 protected virtual bool ViewStateIgnoresCase
506                 {
507                         get {
508                                 return false;
509                         }
510                 }
511
512                 internal bool AutoEventWireup {
513                         get { return (stateMask & AUTO_EVENT_WIREUP) != 0; }
514                         set { SetMask (AUTO_EVENT_WIREUP, value); }
515                 }
516
517                 internal void SetBindingContainer (bool isBC)
518                 {
519                         SetMask (BINDING_CONTAINER, isBC);
520                 }
521
522                 internal void ResetChildNames ()
523                 {
524                         defaultNumberID = 0;
525                 }
526
527                 string GetDefaultName ()
528                 {
529                         string defaultName;
530                         if (defaultNumberID > 99) {
531                                 defaultName = "_ctl" + defaultNumberID++;
532                         } else {
533                                 defaultName = defaultNameArray [defaultNumberID++];
534                         }
535                         return defaultName;
536                 }
537
538                 void NullifyUniqueID ()
539                 {
540                         uniqueID = null;
541                         if (!HasControls ())
542                                 return;
543
544                         foreach (Control c in _controls)
545                                 c.NullifyUniqueID ();
546                 }
547
548                 protected internal virtual void AddedControl (Control control, int index)
549                 {
550                         /* Ensure the control don't have more than 1 parent */
551                         if (control._parent != null)
552                                 control._parent.Controls.Remove (control);
553
554                         control._parent = this;
555                         control._page = _page;
556                         Control nc = ((stateMask & IS_NAMING_CONTAINER) != 0) ? this : NamingContainer;
557
558                         if (nc != null) {
559                                 control._namingContainer = nc;
560                                 if (control.AutoID == true && control._userId == null)
561                                         control._userId =  nc.GetDefaultName ();
562                         }
563
564                         if ((stateMask & (INITING | INITED)) != 0)
565                                 control.InitRecursive (nc);
566
567                         if ((stateMask & (VIEWSTATE_LOADED | LOADED)) != 0) {
568                                 if (pendingVS != null) {
569                                         object vs = pendingVS [index];
570                                         if (vs != null) {
571                                                 pendingVS.Remove (index);
572                                                 if (pendingVS.Count == 0)
573                                                         pendingVS = null;
574                                         
575                                                 control.LoadViewStateRecursive (vs);
576                                         }
577                                 }
578                         }
579
580                         if ((stateMask & LOADED) != 0)
581                                 control.LoadRecursive ();
582                         
583                         if ((stateMask & PRERENDERED) != 0)
584                                 control.PreRenderRecursiveInternal ();
585                 }
586
587                 protected virtual void AddParsedSubObject(object obj) //DIT
588                 {
589                         Control c = obj as Control;
590                         if (c != null) Controls.Add(c);
591                 }
592
593 #if NET_2_0
594                 [EditorBrowsable (EditorBrowsableState.Advanced)]
595                 public virtual void ApplyStyleSheetSkin (Page page)
596                 {
597                         throw new NotImplementedException ();
598                 }
599 #endif          
600
601                 protected void BuildProfileTree(string parentId, bool calcViewState)
602                 {
603                         //TODO
604                 }
605
606 #if NET_2_0
607                 protected void ClearChildControlState ()
608                 {
609                         throw new NotImplementedException ();
610                 }
611
612                 protected void ClearChildState ()
613                 {
614                         throw new NotImplementedException ();
615                 }
616 #endif          
617
618                 protected void ClearChildViewState ()
619                 {
620                         pendingVS = null;
621                 }
622
623 #if NET_2_0
624                 protected internal
625 #else
626                 protected
627 #endif          
628                 virtual void CreateChildControls() {} //DIT
629                 
630                 protected virtual ControlCollection CreateControlCollection() //DIT
631                 {
632                         return new ControlCollection(this);
633                 }
634
635                 protected virtual void EnsureChildControls ()
636                 {
637                         if (ChildControlsCreated == false && (stateMask & CREATING_CONTROLS) == 0) {
638                                 stateMask |= CREATING_CONTROLS;
639 #if NET_2_0
640                                 if (Adapter != null)
641                                         Adapter.CreateChildControls ();
642                                 else
643 #endif
644                                         CreateChildControls();
645                                 ChildControlsCreated = true;
646                                 stateMask &= ~CREATING_CONTROLS;
647                         }
648                 }
649
650 #if NET_2_0
651                 protected void EnsureID ()
652                 {
653                         throw new NotImplementedException ();
654                 }
655
656                 protected bool HasEvents ()
657                 {
658                         throw new NotImplementedException ();
659                 }
660                 
661 #endif
662                 
663
664                 protected bool IsLiteralContent()
665                 {
666                         if (HasControls () && _controls.Count == 1 && (_controls [0] is LiteralControl))
667                                 return true;
668
669                         return false;
670                 }
671
672                 [WebSysDescription ("")]
673                 public virtual Control FindControl (string id)
674                 {
675                         return FindControl (id, 0);
676                 }
677
678                 Control LookForControlByName (string id)
679                 {
680                         if (!HasControls ())
681                                 return null;
682
683                         Control result = null;
684                         foreach (Control c in _controls) {
685                                 if (String.Compare (id, c._userId, true) == 0) {
686                                         if (result != null && result != c) {
687                                                 throw new HttpException ("1 Found more than one control with ID '" + id + "'");
688                                         }
689
690                                         result = c;
691                                         continue;
692                                 }
693
694                                 if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ()) {
695                                         Control child = c.LookForControlByName (id);
696                                         if (child != null) {
697                                                 if (result != null && result != child)
698                                                         throw new HttpException ("2 Found more than one control with ID '" + id + "'");
699
700                                                 result = child;
701                                         }
702                                 }
703                         }
704
705                         return result;
706                 }
707
708                 protected virtual Control FindControl (string id, int pathOffset)
709                 {
710                         EnsureChildControls ();
711                         Control namingContainer = null;
712                         if ((stateMask & IS_NAMING_CONTAINER) == 0) {
713                                 namingContainer = NamingContainer;
714                                 if (namingContainer == null)
715                                         return null;
716
717                                 return namingContainer.FindControl (id, pathOffset);
718                         }
719
720                         if (!HasControls ())
721                                 return null;
722
723                         int colon = id.IndexOf (':', pathOffset);
724                         if (colon == -1)
725                                 return LookForControlByName (id.Substring (pathOffset));
726                         
727                         string idfound = id.Substring (pathOffset, colon - pathOffset);
728                         namingContainer = LookForControlByName (idfound);
729                         if (namingContainer == null)
730                                 return null;
731
732                         return namingContainer.FindControl (id, colon + 1);
733                 }
734
735                 protected virtual void LoadViewState(object savedState)
736                 {
737                         if (savedState != null) {
738                                 ViewState.LoadViewState (savedState);
739                                 object o = ViewState ["Visible"];
740                                 if (o != null) {
741                                         SetMask (VISIBLE, (bool) o);
742                                         stateMask |= VISIBLE_CHANGED;
743                                 }
744                         }
745                 }
746
747                 [MonoTODO("Secure?")]
748                 protected string MapPathSecure(string virtualPath)
749                 {
750                         string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
751                         return Context.Request.MapPath (combined);
752                 }
753
754                 protected virtual bool OnBubbleEvent(object source, EventArgs args) //DIT
755                 {
756 #if MONO_TRACE
757                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
758                         string type_name = null;
759                         if (trace != null) {
760                                 type_name = GetType ().Name;
761                                 trace.Write ("control", String.Format ("OnBubbleEvent {0} {1}", _userId, type_name));
762                         }
763 #endif
764                         return false;
765                 }
766
767                 protected virtual void OnDataBinding (EventArgs e)
768                 {
769                         if ((event_mask & databinding_mask) != 0) {
770                                 EventHandler eh = (EventHandler)(_events [DataBindingEvent]);
771                                 if (eh != null) {
772 #if MONO_TRACE
773                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
774                                         string type_name = null;
775                                         if (trace != null) {
776                                                 type_name = GetType ().Name;
777                                                 trace.Write ("control", String.Format ("OnDataBinding {0} {1}", _userId, type_name));
778                                         }
779 #endif
780                                         eh (this, e);
781                                 }
782                         }
783                 }
784
785 #if NET_2_0
786                 protected internal
787 #else           
788                 protected
789 #endif          
790                 virtual void OnInit (EventArgs e)
791                 {
792                         if ((event_mask & init_mask) != 0) {
793                                 EventHandler eh = (EventHandler)(_events [InitEvent]);
794                                 if (eh != null) {
795 #if MONO_TRACE
796                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
797                                         string type_name = null;
798                                         if (trace != null) {
799                                                 type_name = GetType ().Name;
800                                                 trace.Write ("control", String.Format ("OnInit {0} {1}", _userId, type_name));
801                                         }
802 #endif
803                                         eh (this, e);
804                                 }
805                         }
806                 }
807
808 #if NET_2_0
809                 protected internal
810 #else
811                 protected
812 #endif          
813                 virtual void OnLoad (EventArgs e)
814                 {
815                         if ((event_mask & load_mask) != 0) {
816                                 EventHandler eh = (EventHandler)(_events [LoadEvent]);
817                                 if (eh != null) {
818 #if MONO_TRACE
819                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
820                                         string type_name = null;
821                                         if (trace != null) {
822                                                 type_name = GetType ().Name;
823                                                 trace.Write ("control", String.Format ("OnLoad {0} {1}", _userId, type_name));
824                                         }
825 #endif
826                                         eh (this, e);
827                                 }
828                         }
829                 }
830
831 #if NET_2_0
832                 protected internal
833 #else
834                 protected
835 #endif
836                 virtual void OnPreRender (EventArgs e)
837                 {
838                         if ((event_mask & prerender_mask) != 0) {
839                                 EventHandler eh = (EventHandler)(_events [PreRenderEvent]);
840                                 if (eh != null) {
841 #if MONO_TRACE
842                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
843                                         string type_name = null;
844                                         if (trace != null) {
845                                                 type_name = GetType ().Name;
846                                                 trace.Write ("control", String.Format ("OnPreRender {0} {1}", _userId, type_name));
847                                         }
848 #endif
849                                         eh (this, e);
850                                 }
851                         }
852                 }
853
854 #if NET_2_0
855                 protected internal
856 #else
857                 protected
858 #endif
859                 virtual void OnUnload(EventArgs e)
860                 {
861                         if ((event_mask & unload_mask) != 0) {
862                                 EventHandler eh = (EventHandler)(_events [UnloadEvent]);
863                                 if (eh != null) {
864 #if MONO_TRACE
865                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
866                                         string type_name = null;
867                                         if (trace != null) {
868                                                 type_name = GetType ().Name;
869                                                 trace.Write ("control", String.Format ("OnUnload {0} {1}", _userId, type_name));
870                                         }
871 #endif
872                                         eh (this, e);
873                                 }
874                         }
875                 }
876
877 #if NET_2_0
878                 protected internal Stream OpenFile (string path)
879                 {
880                         throw new NotImplementedException ();
881                 }
882 #endif          
883
884                 protected void RaiseBubbleEvent(object source, EventArgs args)
885                 {
886                         Control c = Parent;
887                         while (c != null) {
888 #if MONO_TRACE
889                                 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
890                                 string type_name = null;
891                                 if (trace != null) {
892                                         type_name = GetType ().Name;
893                                         trace.Write ("control", String.Format ("RaiseBubbleEvent {0} {1}", _userId, type_name));
894                                 }
895 #endif
896                                 if (c.OnBubbleEvent (source, args)) {
897 #if MONO_TRACE
898                                         if (trace != null)
899                                                 trace.Write ("control", String.Format ("End RaiseBubbleEvent (false) {0} {1}", _userId, type_name));
900 #endif
901                                         break;
902                                 }
903 #if MONO_TRACE
904                                 if (trace != null)
905                                         trace.Write ("control", String.Format ("End RaiseBubbleEvent (true) {0} {1}", _userId, type_name));
906 #endif
907                                 c = c.Parent;
908                         }
909                 }
910
911 #if NET_2_0
912                 protected internal
913 #else
914                 protected
915 #endif
916                 virtual void Render(HtmlTextWriter writer) //DIT
917                 {
918                         RenderChildren(writer);
919                 }
920
921 #if NET_2_0
922                 protected internal
923 #else
924                 protected
925 #endif
926                 virtual void RenderChildren (HtmlTextWriter writer) //DIT
927                 {
928                         if (_renderMethodDelegate != null) {
929                                 _renderMethodDelegate (writer, this);
930                         } else if (_controls != null) {
931                                 int len = _controls.Count;
932                                 for (int i = 0; i < len; i++) {
933                                         Control c = _controls [i];
934 #if NET_2_0
935                                         if (c.Adapter != null)
936                                                 c.RenderControl (writer, c.Adapter);
937                                         else
938 #endif
939                                                 c.RenderControl (writer);
940                                 }
941                         }
942                 }
943
944 #if NET_2_0
945                 protected virtual ControlAdapter ResolveAdapter ()
946                 {
947                         throw new NotImplementedException ();
948                 }
949 #endif          
950
951                 protected virtual object SaveViewState ()
952                 {
953                         if ((stateMask & VISIBLE_CHANGED) != 0) {
954                                 ViewState ["Visible"] = (stateMask & VISIBLE) != 0;
955                         } else if (_viewState == null) {
956                                 return null;
957                         }
958
959                         return _viewState.SaveViewState ();
960                 }
961
962                 protected virtual void TrackViewState()
963                 {
964                         if (_viewState != null)
965                                 _viewState.TrackViewState ();
966
967                         stateMask |= TRACK_VIEWSTATE;
968                 }
969
970                 public virtual void Dispose ()
971                 {
972                         if ((event_mask & disposed_mask) != 0) {
973                                 EventHandler eh = (EventHandler)(_events [DisposedEvent]);
974                                 if (eh != null) eh (this, EventArgs.Empty);
975                         }
976                 }
977
978                 [WebCategory ("FIXME")]
979                 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]
980                 public event EventHandler DataBinding {
981                         add {
982                                 event_mask |= databinding_mask;
983                                 Events.AddHandler (DataBindingEvent, value);
984                         }
985                         remove { Events.RemoveHandler (DataBindingEvent, value); }
986                 }
987
988                 [WebSysDescription ("Raised when the contol is disposed.")]
989                 public event EventHandler Disposed {
990                         add {
991                                 event_mask |= disposed_mask;
992                                 Events.AddHandler (DisposedEvent, value);
993                         }
994                         remove { Events.RemoveHandler (DisposedEvent, value); }
995                 }
996
997                 [WebSysDescription ("Raised when the page containing the control is initialized.")]
998                 public event EventHandler Init {
999                         add {
1000                                 event_mask |= init_mask;
1001                                 Events.AddHandler (InitEvent, value);
1002                         }
1003                         remove { Events.RemoveHandler (InitEvent, value); }
1004                 }
1005
1006                 [WebSysDescription ("Raised after the page containing the control has been loaded.")]
1007                 public event EventHandler Load {
1008                         add {
1009                                 event_mask |= load_mask;
1010                                 Events.AddHandler (LoadEvent, value);
1011                         }
1012                         remove { Events.RemoveHandler (LoadEvent, value); }
1013                 }
1014
1015                 [WebSysDescription ("Raised before the page containing the control is rendered.")]
1016                 public event EventHandler PreRender {
1017                         add {
1018                                 event_mask |= prerender_mask;
1019                                 Events.AddHandler (PreRenderEvent, value);
1020                         }
1021                         remove { Events.RemoveHandler (PreRenderEvent, value); }
1022                 }
1023
1024                 [WebSysDescription ("Raised when the page containing the control is unloaded.")]
1025                 public event EventHandler Unload {
1026                         add {
1027                                 event_mask |= unload_mask;
1028                                 Events.AddHandler (UnloadEvent, value);
1029                         }
1030                         remove { Events.RemoveHandler (UnloadEvent, value); }
1031                 }
1032
1033                 public virtual void DataBind() //DIT
1034                 {
1035                         #if NET_2_0
1036                         DataBind (true);
1037                         #else
1038                         OnDataBinding (EventArgs.Empty);
1039                         DataBindChildren();
1040                         #endif
1041                 }
1042
1043                 #if NET_2_0
1044                 protected virtual
1045                 #endif
1046                 
1047                 void DataBindChildren ()
1048                 {
1049                         if (!HasControls ())
1050                                 return;
1051                         
1052                         int len = _controls.Count;
1053                         for (int i = 0; i < len; i++) {
1054                                 Control c = _controls [i];
1055                                 c.DataBind ();
1056                         }
1057                 }
1058
1059
1060                 public virtual bool HasControls ()
1061                 {
1062                     return (_controls != null && _controls.Count > 0);
1063                 }
1064
1065 #if NET_2_0
1066                 public virtual
1067 #else
1068                 public
1069 #endif
1070                 void RenderControl (HtmlTextWriter writer)
1071                 {
1072                         if ((stateMask & VISIBLE) != 0) {
1073                                 HttpContext ctx = Context;
1074                                 TraceContext trace = (ctx != null) ? ctx.Trace : null;
1075                                 int pos = 0;
1076                                 if ((trace != null) && trace.IsEnabled)
1077                                         pos = ctx.Response.GetOutputByteCount ();
1078
1079                                 Render(writer);
1080                                 if ((trace != null) && trace.IsEnabled) {
1081                                         int size = ctx.Response.GetOutputByteCount () - pos;
1082                                         trace.SaveSize (this, size >= 0 ? size : 0);
1083                                 }
1084                         }
1085                 }
1086
1087 #if NET_2_0
1088                 protected void RenderControl (HtmlTextWriter writer,
1089                                               ControlAdapter adapter)
1090                 {
1091                         if ((stateMask & VISIBLE) != 0) {
1092                                 adapter.BeginRender (writer);
1093                                 adapter.Render (writer);
1094                                 adapter.EndRender (writer);
1095                         }
1096                 }
1097 #endif          
1098
1099                 public string ResolveUrl (string relativeUrl)
1100                 {
1101                         if (relativeUrl == null)
1102                                 throw new ArgumentNullException ("relativeUrl");
1103
1104                         if (relativeUrl == "")
1105                                 return "";
1106
1107                         if (relativeUrl [0] == '#')
1108                                 return relativeUrl;
1109                         
1110                         string ts = TemplateSourceDirectory;
1111                         if (ts == "" || !UrlUtils.IsRelativeUrl (relativeUrl))
1112                                 return relativeUrl;
1113
1114                         HttpResponse resp = Context.Response;
1115                         return resp.ApplyAppPathModifier (UrlUtils.Combine (ts, relativeUrl));
1116                 }
1117                 
1118                 internal bool HasRenderMethodDelegate () {
1119                         return _renderMethodDelegate != null;
1120                 }
1121
1122                 [EditorBrowsable (EditorBrowsableState.Advanced)]
1123                 public void SetRenderMethodDelegate(RenderMethod renderMethod) //DIT
1124                 {
1125                         _renderMethodDelegate = renderMethod;
1126                 }
1127
1128                 internal void LoadRecursive()
1129                 {
1130 #if MONO_TRACE
1131                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1132                         string type_name = null;
1133                         if (trace != null) {
1134                                 type_name = GetType ().Name;
1135                                 trace.Write ("control", String.Format ("LoadRecursive {0} {1}", _userId, type_name));
1136                         }
1137 #endif
1138 #if NET_2_0
1139                         if (Adapter != null)
1140                                 Adapter.OnLoad (EventArgs.Empty);
1141                         else
1142 #endif
1143                                 OnLoad (EventArgs.Empty);
1144                         if (HasControls ()) {
1145                                 int len = _controls.Count;
1146                                 for (int i=0;i<len;i++)
1147                                 {
1148                                         Control c = _controls[i];
1149                                         c.LoadRecursive ();
1150                                 }
1151                         }
1152
1153 #if MONO_TRACE
1154                         if (trace != null)
1155                                 trace.Write ("control", String.Format ("End LoadRecursive {0} {1}", _userId, type_name));
1156 #endif
1157                         stateMask |= LOADED;
1158                 }
1159
1160                 internal void UnloadRecursive(Boolean dispose)
1161                 {
1162 #if MONO_TRACE
1163                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1164                         string type_name = null;
1165                         if (trace != null) {
1166                                 type_name = GetType ().Name;
1167                                 trace.Write ("control", String.Format ("UnloadRecursive {0} {1}", _userId, type_name));
1168                         }
1169 #endif
1170                         if (HasControls ()) {
1171                                 int len = _controls.Count;
1172                                 for (int i=0;i<len;i++)
1173                                 {
1174                                         Control c = _controls[i];                                       
1175                                         c.UnloadRecursive (dispose);
1176                                 }
1177                         }
1178
1179 #if MONO_TRACE
1180                         if (trace != null)
1181                                 trace.Write ("control", String.Format ("End UnloadRecursive {0} {1}", _userId, type_name));
1182 #endif
1183 #if NET_2_0
1184                         if (Adapter != null)
1185                                 Adapter.OnUnload (EventArgs.Empty);
1186                         else
1187 #endif
1188                                 OnUnload (EventArgs.Empty);
1189                         if (dispose)
1190                                 Dispose();
1191                 }
1192
1193                 internal void PreRenderRecursiveInternal()
1194                 {
1195                         if ((stateMask & VISIBLE) != 0) {
1196                                 EnsureChildControls ();
1197 #if MONO_TRACE
1198                                 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1199                                 string type_name = null;
1200                                 if (trace != null) {
1201                                         type_name = GetType ().Name;
1202                                         trace.Write ("control", String.Format ("PreRenderRecursive {0} {1}", _userId, type_name));
1203                                 }
1204 #endif
1205 #if NET_2_0
1206                                 if (Adapter != null)
1207                                         Adapter.OnPreRender (EventArgs.Empty);
1208                                 else
1209 #endif
1210                                         OnPreRender (EventArgs.Empty);
1211                                 if (!HasControls ())
1212                                         return;
1213                                 
1214                                 int len = _controls.Count;
1215                                 for (int i=0;i<len;i++)
1216                                 {
1217                                         Control c = _controls[i];
1218                                         c.PreRenderRecursiveInternal ();
1219                                 }
1220 #if MONO_TRACE
1221                                 if (trace != null)
1222                                         trace.Write ("control", String.Format ("End PreRenderRecursive {0} {1}", _userId, type_name));
1223 #endif
1224                         }
1225                         stateMask |= PRERENDERED;
1226                 }
1227
1228                 internal void InitRecursive(Control namingContainer)
1229                 {
1230 #if MONO_TRACE
1231                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1232                         string type_name = null;
1233                         if (trace != null) {
1234                                 type_name = GetType ().Name;
1235                                 trace.Write ("control", String.Format ("InitRecursive {0} {1}", _userId, type_name));
1236                         }
1237 #endif
1238
1239                         if (HasControls ()) {
1240                                 if ((stateMask & IS_NAMING_CONTAINER) != 0)
1241                                         namingContainer = this;
1242
1243                                 if (namingContainer != null && 
1244                                     namingContainer._userId == null &&
1245                                     namingContainer.AutoID)
1246                                         namingContainer._userId = namingContainer.GetDefaultName () + "b";
1247
1248                                 int len = _controls.Count;
1249                                 for (int i=0;i<len;i++)
1250                                 {
1251                                         Control c = _controls[i];
1252                                         c._page = Page;
1253                                         c._namingContainer = namingContainer;
1254                                         if (namingContainer != null && c._userId == null && c.AutoID)
1255                                                 c._userId = namingContainer.GetDefaultName () + "c";
1256                                         c.InitRecursive (namingContainer);      
1257                                 }
1258                         }
1259
1260                         stateMask |= INITING;
1261 #if NET_2_0
1262                         if (Adapter != null)
1263                                 Adapter.OnInit (EventArgs.Empty);
1264                         else
1265 #endif
1266                                 OnInit (EventArgs.Empty);
1267 #if MONO_TRACE
1268                         if (trace != null)
1269                                 trace.Write ("control", String.Format ("End InitRecursive {0} {1}", _userId, type_name));
1270 #endif
1271                         TrackViewState ();
1272                         stateMask |= INITED;
1273                         stateMask &= ~INITING;
1274                 }
1275
1276                 internal object SaveViewStateRecursive ()
1277                 {
1278                         if (!EnableViewState)
1279                                 return null;
1280
1281 #if MONO_TRACE
1282                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1283                         string type_name = null;
1284                         if (trace != null) {
1285                                 type_name = GetType ().Name;
1286                                 trace.Write ("control", String.Format ("SaveViewStateRecursive {0} {1}", _userId, type_name));
1287                         }
1288 #endif
1289
1290                         ArrayList controlList = null;
1291                         ArrayList controlStates = null;
1292
1293                         int idx = -1;
1294                         if (HasControls ())
1295                         {
1296                                 int len = _controls.Count;
1297                                 for (int i=0;i<len;i++)
1298                                 {
1299                                         Control ctrl = _controls[i];
1300                                         object ctrlState = ctrl.SaveViewStateRecursive ();
1301                                         idx++;
1302                                         if (ctrlState == null)
1303                                                 continue;
1304
1305                                         if (controlList == null) 
1306                                         {
1307                                                 controlList = new ArrayList ();
1308                                                 controlStates = new ArrayList ();
1309                                         }
1310
1311                                         controlList.Add (idx);
1312                                         controlStates.Add (ctrlState);
1313                                 }
1314                         }
1315
1316                         object thisState = SaveViewState ();
1317                         if (thisState == null && controlList == null && controlStates == null) {
1318 #if MONO_TRACE
1319                                 if (trace != null) {
1320                                         trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved nothing", _userId, type_name));
1321                                         trace.SaveViewState (this, null);
1322                                 }
1323 #endif
1324                                 return null;
1325                         }
1326
1327 #if MONO_TRACE
1328                         if (trace != null) {
1329                                 trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved a Triplet", _userId, type_name));
1330                                 trace.SaveViewState (this, thisState);
1331                         }
1332 #endif
1333                         return new Triplet (thisState, controlList, controlStates);
1334                 }
1335                 
1336                 internal void LoadViewStateRecursive (object savedState)
1337                 {
1338                         if (!EnableViewState || savedState == null)
1339                                 return;
1340
1341 #if MONO_TRACE
1342                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1343                         string type_name = null;
1344                         if (trace != null) {
1345                                 type_name = GetType ().Name;
1346                                 trace.Write ("control", String.Format ("LoadViewStateRecursive {0} {1}", _userId, type_name));
1347                         }
1348 #endif
1349                         Triplet savedInfo = (Triplet) savedState;
1350                         LoadViewState (savedInfo.First);
1351
1352                         ArrayList controlList = savedInfo.Second as ArrayList;
1353                         if (controlList == null)
1354                                 return;
1355                         ArrayList controlStates = savedInfo.Third as ArrayList;
1356                         int nControls = controlList.Count;
1357                         for (int i = 0; i < nControls; i++) {
1358                                 int k = (int) controlList [i];
1359                                 if (k < Controls.Count && controlStates != null) {
1360                                         Control c = Controls [k];
1361                                         c.LoadViewStateRecursive (controlStates [i]);
1362                                 } else {
1363                                         if (pendingVS == null)
1364                                                 pendingVS = new Hashtable ();
1365
1366                                         pendingVS [k] = controlStates [i];
1367                                 }
1368                         }
1369
1370 #if MONO_TRACE
1371                         if (trace != null)
1372                                 trace.Write ("control", String.Format ("End LoadViewStateRecursive {0} {1}", _userId, type_name));
1373 #endif
1374                         stateMask |= VIEWSTATE_LOADED;
1375                 }
1376                 
1377                 internal bool AutoID
1378                 {
1379                         get { return (stateMask & AUTOID) != 0; }
1380                         set {
1381                                 if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
1382                                         return;
1383
1384                                 SetMask (AUTOID, value);
1385                         }
1386                 }
1387
1388                 protected internal virtual void RemovedControl (Control control)
1389                 {
1390                         control.UnloadRecursive (false);
1391                         control._parent = null;
1392                         control._page = null;
1393                         control._namingContainer = null;
1394                 }
1395
1396
1397 #if NET_2_0
1398
1399                 string skinId = string.Empty;
1400                 
1401                 [Browsable (false)]
1402                 [Themeable (false)]
1403                 [DefaultValue (true)]
1404                 public virtual bool EnableTheming
1405                 {
1406                         get { return (stateMask & ENABLE_THEMING) != 0; }
1407                         set { SetMask (ENABLE_THEMING, value); }
1408                 }
1409                 
1410                 [Browsable (false)]
1411                 [DefaultValue ("")]
1412                 [Filterable (false)]
1413                 public virtual string SkinID
1414                 {
1415                         get { return skinId; }
1416                         set { skinId = value; }
1417                 }
1418                 
1419                 public string ResolveClientUrl (string url)
1420                 {
1421                         throw new NotImplementedException ();               
1422                 }
1423
1424                 ControlBuilder IControlBuilderAccessor.ControlBuilder { 
1425                         get {throw new NotImplementedException (); }
1426                 }
1427
1428                 IDictionary IControlDesignerAccessor.GetDesignModeState ()
1429                 {
1430                         throw new NotImplementedException ();               
1431                 }
1432
1433                 void IControlDesignerAccessor.SetDesignModeState (IDictionary designData)
1434                 {
1435                         SetDesignModeState (designData);
1436                 }
1437         
1438                 void IControlDesignerAccessor.SetOwnerControl (Control control)
1439                 {
1440                         throw new NotImplementedException ();               
1441                 }
1442                 
1443                 IDictionary IControlDesignerAccessor.UserData { 
1444                         get { throw new NotImplementedException (); }
1445                 }
1446        
1447                 ExpressionBindingCollection expressionBindings;
1448
1449                 ExpressionBindingCollection IExpressionsAccessor.Expressions { 
1450                         get { 
1451                                 if (expressionBindings == null)
1452                                         expressionBindings = new ExpressionBindingCollection ();
1453                                 return expressionBindings;
1454                         } 
1455                 }
1456                 
1457                 bool IExpressionsAccessor.HasExpressions { 
1458                         get {
1459                                 return (expressionBindings != null && expressionBindings.Count > 0);
1460                         }
1461                 }
1462
1463                 [MonoTODO]
1464                 public virtual void Focus()
1465                 {
1466                         throw new NotImplementedException();
1467                 }
1468                 
1469                 protected internal virtual void LoadControlState (object state)
1470                 {
1471                 }
1472                 
1473                 protected internal virtual object SaveControlState ()
1474                 {
1475                         return null;
1476                 }
1477                 
1478                 protected virtual void DataBind (bool raiseOnDataBinding)
1479                 {
1480                         bool foundDataItem = false;
1481                         
1482                         if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
1483                                 object o = DataBinder.GetDataItem (this, out foundDataItem);
1484                                 if (foundDataItem)
1485                                         Page.PushDataItemContext (o);
1486                         }
1487                         
1488                         try {
1489                                 
1490                                 if (raiseOnDataBinding)
1491                                         OnDataBinding (EventArgs.Empty);
1492                                 DataBindChildren();
1493                         
1494                         } finally {
1495                                 if (foundDataItem)
1496                                         Page.PopDataItemContext ();
1497                         }
1498                 }
1499                 
1500                 protected virtual IDictionary GetDesignModeState ()
1501                 {
1502                         throw new NotImplementedException ();               
1503                 }
1504                 
1505                 protected virtual void SetDesignModeState (IDictionary data)
1506                 {
1507                         throw new NotImplementedException ();               
1508                 }
1509 #endif
1510                 void IParserAccessor.AddParsedSubObject (object obj) {
1511                         this.AddParsedSubObject (obj);
1512                 }
1513
1514                 DataBindingCollection IDataBindingsAccessor.DataBindings {
1515                         get {
1516                                 if (dataBindings == null) {
1517                                         dataBindings = new DataBindingCollection ();
1518                                 }
1519                                 return dataBindings;
1520                         }
1521                 }
1522
1523                 bool IDataBindingsAccessor.HasDataBindings {
1524                         get {
1525                                 if (dataBindings != null && dataBindings.Count > 0) {
1526                                         return true;
1527                                 }
1528                                 return false;
1529                         }
1530                 }
1531         }
1532 }