fde93160d3fa0bfaa5ff2913b6d81aab56f3823d
[mono.git] / mcs / class / System.Web / System.Web.UI / Control.cs
1 //\r
2 // System.Web.UI.Control.cs\r
3 //\r
4 // Author:\r
5 //   Bob Smith <bob@thestuff.net>\r
6 //\r
7 // (C) Bob Smith\r
8 //\r
9 \r
10 /*\r
11  * Maintainer: bob@thestuff.net, gvaish@iitk.ac.in\r
12  * (C) Bob Smith, Gaurav Vaish\r
13  */\r
14 \r
15 //notes: view state only tracks changes after OnInit method is executed for the page request. You can read from it at any time, but cant write to it during rendering.\r
16 //even more notes: view state info in trackviewstate method description. read later.\r
17 //Ok, enough notes: what the heck is different between enable view state, and track view state.\r
18 //Well, maybe not. How does the ViewState know when to track changes? Does it look at the property\r
19 //on the owning control, or does it have a method/property of its own that gets called?\r
20 // I think this last question is solved in the Interface for it. Look into this.\r
21 \r
22 //cycle:\r
23 //init is called when control is first created.\r
24 //load view state ic called right after init to populate the view state.\r
25 //loadpostdata is called if ipostbackdatahandler is implemented.\r
26 //load is called when control is loaded into a page\r
27 //raisepostdatachangedevent if ipostbackdatahandler is implemented.\r
28 //raisepostbackevent if ipostbackeventhandler is implemented.\r
29 //prerender is called when the server is about to render its page object\r
30 //SaveViewState is called.\r
31 //Unload then dispose it apears. :)\r
32 \r
33 //Naming Container MUST have some methods. What are they? No clue. Help?\r
34 \r
35 //read this later. http://gotdotnet.com/quickstart/aspplus/\r
36 //This to: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguidnf/html/cpconattributesdesign-timesupport.asp\r
37 //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguidnf/html/cpcontracefunctionality.asp\r
38 \r
39 // Isnt life grand? :)\r
40 // See the undocumented methods? Gota love um. ;)\r
41 // ASP.test4_aspx.Page_Load(Object Sender, EventArgs e) in \\genfs2\www24\bobsmith11\test4.aspx:6\r
42 // System.Web.UI.Control.OnLoad(EventArgs e) +67\r
43 // System.Web.UI.Control.LoadRecursive() +73\r
44 // System.Web.UI.Page.ProcessRequestMain() +394\r
45 \r
46 // ASP.test4_aspx.Page_Unload(Object Sender, EventArgs e) in \\genfs2\www24\bobsmith11\test4.aspx:6\r
47 // System.EventHandler.Invoke(Object sender, EventArgs e) +0\r
48 // System.Web.UI.Control.OnUnload(EventArgs e) +67\r
49 // System.Web.UI.Control.UnloadRecursive(Boolean dispose) +78\r
50 // System.Web.UI.Page.ProcessRequest() +194\r
51 // System.Web.UI.Page.ProcessRequest(HttpContext context) +18\r
52 // System.Web.CallHandlerExecutionStep.Execute() +179\r
53 // System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +87\r
54 \r
55 \r
56 // ASP.test4_aspx.Page_Unload(Object Sender, EventArgs e) in \\genfs2\www24\bobsmith11\test4.aspx:6\r
57 // System.Web.UI.Control.OnUnload(EventArgs e) +67\r
58 // System.Web.UI.Control.UnloadRecursive(Boolean dispose) +78\r
59 // System.Web.UI.Page.ProcessRequest()\r
60 \r
61 // ASP.test4_aspx.Page_Kill(Object Sender, EventArgs e) in \\genfs2\www24\bobsmith11\test4.aspx:6\r
62 // System.Web.UI.Control.OnPreRender(EventArgs e) +67\r
63 // System.Web.UI.Control.PreRenderRecursiveInternal() +61\r
64 // System.Web.UI.Page.ProcessRequestMain() +753\r
65 \r
66 // ASP.test4_aspx.OnInit(EventArgs e) in \\genfs2\www24\bobsmith11\test4.aspx:6\r
67 // System.Web.UI.Control.InitRecursive(Control namingContainer) +202\r
68 // System.Web.UI.Page.ProcessRequestMain() +120\r
69 \r
70 // ASP.test4_aspx.SaveViewState() in \\genfs2\www24\bobsmith11\test4.aspx:12\r
71 // System.Web.UI.Control.SaveViewStateRecursive() +51\r
72 // System.Web.UI.Page.SavePageViewState() +174\r
73 // System.Web.UI.Page.ProcessRequestMain() +861\r
74 \r
75 // ASP.test_aspx.LoadViewState(Object t) +28\r
76 // System.Web.UI.Control.LoadViewStateRecursive(Object savedState) +125\r
77 // System.Web.UI.Page.LoadPageViewState() +182\r
78 // System.Web.UI.Page.ProcessRequestMain() +256\r
79 \r
80 using System;\r
81 using System.Collections;\r
82 using System.Web;\r
83 using System.ComponentModel;\r
84 \r
85 namespace System.Web.UI\r
86 {\r
87         public class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor\r
88         {\r
89                 private static readonly object DataBindingEvent = new object();\r
90                 private static readonly object DisposedEvent = new object();\r
91                 private static readonly object InitEvent = new object();\r
92                 private static readonly object LoadEvent = new object();\r
93                 private static readonly object PreRenderEvent = new object();\r
94                 private static readonly object UnloadEvent = new object();\r
95                 private string _userId = null;\r
96                 private string _cachedUserId = null;\r
97                 private string _cachedClientId = null;\r
98                 private ControlCollection _controls = null;\r
99                 private bool _enableViewState = true;\r
100                 private IDictionary _childViewStates = null; //TODO: Not sure datatype. Placeholder guess.\r
101                 private bool _isNamingContainer = false;\r
102                 private Control _namingContainer = null;\r
103                 private Page _page = null;\r
104                 private Control _parent = null;\r
105                 private ISite _site = null;\r
106                 private bool _visible = true;\r
107                 private HttpContext _context = null;\r
108                 private bool _childControlsCreated = false;\r
109                 private StateBag _viewState = null;\r
110                 private bool _trackViewState = false;\r
111                 private EventHandlerList _events = new EventHandlerList();\r
112                 private RenderMethod _renderMethodDelegate = null;\r
113                 \r
114                     private DataBindingCollection dataBindings = null;\r
115 \r
116                 public Control()\r
117                 {\r
118                         if (this is INamingContainer) _isNamingContainer = true;\r
119                 }\r
120                 public virtual string ClientID //DIT\r
121                 {\r
122                         get\r
123                         {\r
124                                 if (_cachedUserId != null && _cachedClientId != null)\r
125                                         return _cachedClientId;\r
126                                 _cachedUserId = UniqueID.Replace(':', '_');\r
127                                 return _cachedUserId;\r
128                         }\r
129                 }\r
130                 public virtual ControlCollection Controls //DIT\r
131                 {\r
132                         get\r
133                         {\r
134                                 if (_controls == null) _controls = CreateControlCollection();\r
135                                 return _controls;\r
136                         }\r
137                 }\r
138                 public virtual bool EnableViewState //DIT\r
139                 {\r
140                         get\r
141                         {\r
142                                 return _enableViewState;\r
143                         }\r
144                         set\r
145                         {\r
146                                 _enableViewState = value;\r
147                         }\r
148                 }\r
149                 public virtual string ID\r
150                 {\r
151                         get //DIT\r
152                         {\r
153                                 return _userId;\r
154                         }\r
155                         set\r
156                         {\r
157                                 if (value == null || value == "") return;\r
158                                 _userId = value;\r
159                                 _cachedUserId = null;\r
160                                 //TODO: Some Naming Container stuff here I think.\r
161                         }\r
162                 }\r
163                 public virtual Control NamingContainer //DIT\r
164                 {\r
165                         get\r
166                         {\r
167                                 if (_namingContainer == null && _parent != null)\r
168                                 {\r
169                                         if (_parent._isNamingContainer == false)\r
170                                                 _namingContainer = _parent.NamingContainer;\r
171                                         else\r
172                                                 _namingContainer = _parent;\r
173                                 }\r
174                                 return _namingContainer;\r
175                         }\r
176                 }\r
177                 public virtual Page Page //DIT\r
178                 {\r
179                         get\r
180                         {\r
181                                 if (_page == null && _parent != null) _page = _parent.Page;\r
182                                 return _page;\r
183                         }\r
184                         set\r
185                         {\r
186                                 _page = value;\r
187                         }\r
188                 }\r
189                 public virtual Control Parent //DIT\r
190                 {\r
191                         get\r
192                         {\r
193                                 return _parent;\r
194                         }\r
195                 }\r
196                 public ISite Site //DIT\r
197                 {\r
198                         get\r
199                         {\r
200                                 return _site;\r
201                         }\r
202                         set\r
203                         {\r
204                                 _site = value;\r
205                         }\r
206                 }\r
207                 public virtual string TemplateSourceDirectory\r
208                 {\r
209                         get\r
210                         {\r
211                                 return Context.Request.ApplicationPath; //TODO: Dont think this is right.\r
212                         }\r
213                 }\r
214                 public virtual string UniqueID\r
215                 {\r
216                         get\r
217                         {\r
218                                 //TODO: Some Naming container methods here. What are they? Why arnt they declared?\r
219                                 //Note: Nuked the old stuff here. Was total crap. :)\r
220                                 throw new NotImplementedException();\r
221                         }\r
222                 }\r
223                 public virtual bool Visible\r
224                 { //TODO: Are children visible when parents are not?\r
225                         get\r
226                         {\r
227                                 return _visible;\r
228                         }\r
229                         set\r
230                         {\r
231                                 _visible = value;\r
232                         }\r
233                 }\r
234                 protected bool ChildControlsCreated //DIT\r
235                 {\r
236                         get\r
237                         {\r
238                                 return _childControlsCreated;\r
239                         }\r
240                         set\r
241                         {\r
242                                 if (value == false && _childControlsCreated == true)\r
243                                         _controls.Clear();\r
244                                 _childControlsCreated = value;\r
245                         }\r
246                 }\r
247                 protected virtual HttpContext Context //DIT\r
248                 {\r
249                         get\r
250                         {\r
251                                 HttpContext context;\r
252                                 if (_context != null)\r
253                                         return _context;\r
254                                 if (_parent == null)\r
255                                         return HttpContext.Current;\r
256                                 context = _parent.Context;\r
257                                 if (context != null)\r
258                                         return context;\r
259                                 return HttpContext.Current;\r
260                         }\r
261                 }\r
262                 protected EventHandlerList Events //DIT\r
263                 {\r
264                         get\r
265                         {\r
266                                 if (_events == null)\r
267                                 {\r
268                                         _events = new EventHandlerList();\r
269                                 }\r
270                                 return _events;\r
271                         }\r
272                 }\r
273                 protected bool HasChildViewState //DIT\r
274                 {\r
275                         get\r
276                         {\r
277                                 if (_childViewStates == null) return false;\r
278                                 return true;\r
279                         }\r
280                 }\r
281                 protected bool IsTrackingViewState //DIT\r
282                 {\r
283                         get\r
284                         {\r
285                                 return _trackViewState;\r
286                         }\r
287                 }\r
288                 protected virtual StateBag ViewState\r
289                 {\r
290                         get\r
291                         {\r
292                                 if(_viewState == null)\r
293                                 {\r
294                                         _viewState = new StateBag(ViewStateIgnoresCase);\r
295                                 if(IsTrackingViewState)\r
296                                                 _viewState.TrackViewState();\r
297                                 }\r
298                                 return _viewState;\r
299                         }\r
300                 }\r
301                 protected virtual bool ViewStateIgnoresCase //DIT\r
302                 {\r
303                         get\r
304                         {\r
305                                 return true;\r
306                         }\r
307                 }\r
308                 protected virtual void AddParsedSubObject(object obj) //DIT\r
309                 {\r
310                         Control c = (Control)obj;\r
311                         if (c != null) Controls.Add(c);\r
312                 }\r
313                 protected void BuildProfileTree(string parentId, bool calcViewState)\r
314                 {\r
315                         //TODO\r
316                 }\r
317                 protected void ClearChildViewState()\r
318                 {\r
319                         //TODO\r
320                         //Not quite sure about this. an example clears children then calls this, so I think\r
321                         //view state is local to the current object, not children.\r
322                 }\r
323                 protected virtual void CreateChildControls() {} //DIT\r
324                 protected virtual ControlCollection CreateControlCollection() //DIT\r
325                 {\r
326                         return new ControlCollection(this);\r
327                 }\r
328                 protected virtual void EnsureChildControls() //DIT\r
329                 {\r
330                         if (_childControlsCreated == false)\r
331                         {\r
332                                 CreateChildControls();\r
333                                 ChildControlsCreated = true;\r
334                         }\r
335                 }\r
336                 protected virtual Control FindControl(string id, int pathOffset)\r
337                 {\r
338                         //TODO: I think there is Naming Container stuff here. Redo.\r
339                         int i;\r
340                         for (i = pathOffset; i < _controls.Count; i++)\r
341                                 if (_controls[i].ID == id) return _controls[i];\r
342                         return null;\r
343                 }\r
344                 protected virtual void LoadViewState(object savedState)\r
345                 {\r
346                         //TODO: What should I do by default?\r
347                 }\r
348                 protected string MapPathSecure(string virtualPath)\r
349                 {\r
350                         throw new NotImplementedException();\r
351                         //TODO: Need to read up on security+web.\r
352                 }\r
353                 protected virtual bool OnBubbleEvent(object source, EventArgs args) //DIT\r
354                 {\r
355                         return false;\r
356                 }\r
357                 protected virtual void OnDataBinding(EventArgs e) //DIT\r
358                 {\r
359                         if (_events != null)\r
360                         {\r
361                                 EventHandler eh = (EventHandler)(_events[DataBindingEvent]);\r
362                                 if (eh != null) eh(this, e);\r
363                         }\r
364                 }\r
365                 protected virtual void OnInit(EventArgs e) //DIT\r
366                 {\r
367                         if (_events != null)\r
368                         {\r
369                                 EventHandler eh = (EventHandler)(_events[InitEvent]);\r
370                                 if (eh != null) eh(this, e);\r
371                         }\r
372                 }\r
373                 protected virtual void OnLoad(EventArgs e) //DIT\r
374                 {\r
375                         if (_events != null)\r
376                         {\r
377                                 EventHandler eh = (EventHandler)(_events[LoadEvent]);\r
378                                 if (eh != null) eh(this, e);\r
379                         }\r
380                 }\r
381                 protected virtual void OnPreRender(EventArgs e) //DIT\r
382                 {\r
383                         if (_events != null)\r
384                         {\r
385                                 EventHandler eh = (EventHandler)(_events[PreRenderEvent]);\r
386                                 if (eh != null) eh(this, e);\r
387                         }\r
388                 }\r
389                 protected virtual void OnUnload(EventArgs e) //DIT\r
390                 {\r
391                         if (_events != null)\r
392                         {\r
393                                 EventHandler eh = (EventHandler)(_events[UnloadEvent]);\r
394                                 if (eh != null) eh(this, e);\r
395                         }\r
396                 }\r
397                 protected void RaiseBubbleEvent(object source, EventArgs args)\r
398                 {\r
399                         throw new NotImplementedException();\r
400                         //return false;\r
401                 }\r
402                 protected virtual void Render(HtmlTextWriter writer) //DIT\r
403                 {\r
404                         RenderChildren(writer);\r
405                 }\r
406                 protected virtual void RenderChildren(HtmlTextWriter writer) //DIT\r
407                 {\r
408                         if (_renderMethodDelegate != null)\r
409                                 _renderMethodDelegate(writer, this);\r
410                         else if (_controls != null)\r
411                                 foreach (Control c in _controls)\r
412                                         c.RenderControl(writer);\r
413                 }\r
414                 protected virtual object SaveViewState()\r
415                 {\r
416                         return ViewState;\r
417                 }\r
418                 protected virtual void TrackViewState()\r
419                 {\r
420                         _trackViewState = true;\r
421                 }\r
422                 public virtual void Dispose()\r
423                 {\r
424                         //TODO: nuke stuff.\r
425                         throw new NotImplementedException();\r
426                         /*\r
427                         if (_events != null)\r
428                         {\r
429                                 EventHandler eh = (EventHandler)(_events[DisposedEvent]);\r
430                                 if (eh != null) eh(this, e);\r
431                         }\r
432                     */\r
433                 }\r
434                 public event EventHandler DataBinding //DIT\r
435                 {\r
436                         add\r
437                         {\r
438                                 Events.AddHandler(DataBindingEvent, value);\r
439                         }\r
440                         remove\r
441                         {\r
442                                 Events.RemoveHandler(DataBindingEvent, value);\r
443                         }\r
444                 }\r
445                 public event EventHandler Disposed //DIT\r
446                 {\r
447                         add\r
448                         {\r
449                                 Events.AddHandler(DisposedEvent, value);\r
450                         }\r
451                         remove\r
452                         {\r
453                                 Events.RemoveHandler(DisposedEvent, value);\r
454                         }\r
455                 }\r
456                 public event EventHandler Init //DIT\r
457                 {\r
458                         add\r
459                         {\r
460                                 Events.AddHandler(InitEvent, value);\r
461                         }\r
462                         remove\r
463                         {\r
464                                 Events.RemoveHandler(InitEvent, value);\r
465                         }\r
466                 }\r
467                 public event EventHandler Load //DIT\r
468                 {\r
469                         add\r
470                         {\r
471                                 Events.AddHandler(LoadEvent, value);\r
472                         }\r
473                         remove\r
474                         {\r
475                                 Events.RemoveHandler(LoadEvent, value);\r
476                         }\r
477                 }\r
478                 public event EventHandler PreRender //DIT\r
479                 {\r
480                         add\r
481                         {\r
482                                 Events.AddHandler(PreRenderEvent, value);\r
483                         }\r
484                         remove\r
485                         {\r
486                                 Events.RemoveHandler(PreRenderEvent, value);\r
487                         }\r
488                 }\r
489                 public event EventHandler Unload //DIT\r
490                 {\r
491                         add\r
492                         {\r
493                                 Events.AddHandler(UnloadEvent, value);\r
494                         }\r
495                         remove\r
496                         {\r
497                                 Events.RemoveHandler(UnloadEvent, value);\r
498                         }\r
499                 }\r
500                 public virtual void DataBind() //DIT\r
501                 {\r
502                         OnDataBinding(EventArgs.Empty);\r
503                         if (_controls != null)\r
504                                 foreach (Control c in _controls)\r
505                                         c.DataBind();\r
506                 }\r
507                 public virtual Control FindControl(string id) //DIT\r
508                 {\r
509                         return FindControl(id, 0);\r
510                 }\r
511                 public virtual bool HasControls() //DIT\r
512                 {\r
513                         if (_controls != null && _controls.Count >0) return true;\r
514                         return false;\r
515                 }\r
516                 public void RenderControl(HtmlTextWriter writer)\r
517                 {\r
518                         if (_visible)\r
519                         {\r
520                                 //TODO: Something about tracing here.\r
521                                 Render(writer);\r
522                         }\r
523                 }\r
524                 public string ResolveUrl(string relativeUrl)\r
525                 {\r
526                         throw new NotImplementedException();\r
527                 }\r
528                 public void SetRenderMethodDelegate(RenderMethod renderMethod) //DIT\r
529                 {\r
530                         _renderMethodDelegate = renderMethod;\r
531                 }\r
532                 protected void LoadRecursive()\r
533                 {\r
534                         OnLoad(EventArgs.Empty);\r
535                         if (_controls != null) foreach (Control c in _controls) c.LoadRecursive();\r
536                 }\r
537                 protected void UnloadRecursive(Boolean dispose)\r
538                 {\r
539                         OnUnload(EventArgs.Empty);\r
540                         if (_controls != null) foreach (Control c in _controls) c.UnloadRecursive(dispose);\r
541                         if (dispose) Dispose();\r
542                 }\r
543                 protected void PreRenderRecursiveInternal()\r
544                 {\r
545                         OnPreRender(EventArgs.Empty);\r
546                         if (_controls != null) foreach (Control c in _controls) c.PreRenderRecursiveInternal();\r
547                 }\r
548                 protected void InitRecursive(Control namingContainer)\r
549                 {\r
550                         if (_controls != null) foreach (Control c in _controls) c.InitRecursive(namingContainer);\r
551                         OnInit(EventArgs.Empty);\r
552                 }\r
553                 protected object SaveViewStateRecursive()\r
554                 {\r
555                         throw new NotImplementedException();\r
556                 }\r
557                 protected void LoadViewStateRecursive(Object savedState)\r
558                 {\r
559                         throw new NotImplementedException();\r
560                 }\r
561                 \r
562                 void IParserAccessor.AddParsedSubObject(object obj)\r
563                 {\r
564                         this.AddParsedSubObject(obj);\r
565                 }\r
566                 \r
567                 DataBindingCollection IDataBindingsAccessor.DataBindings\r
568                 {\r
569                         get\r
570                         {\r
571                                 if(dataBindings == null)\r
572                                         dataBindings = new DataBindingCollection();\r
573                                 return dataBindings;\r
574                         }\r
575                 }\r
576                 \r
577                 bool IDataBindingsAccessor.HasDataBindings\r
578                 {\r
579                         get\r
580                         {\r
581                                 return (dataBindings!=null && dataBindings.Count>0);\r
582                         }\r
583                 }\r
584                 \r
585                 //TODO: I think there are some needed Interface implementations to do here.\r
586                 //TODO: Find api for INamingContainer.\r
587         }\r
588 }\r