2 // System.Web.UI.Control.cs
\r
5 // Bob Smith <bob@thestuff.net>
\r
11 * Maintainer: bob@thestuff.net, gvaish@iitk.ac.in
\r
12 * (C) Bob Smith, Gaurav Vaish
\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
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
33 //Naming Container MUST have some methods. What are they? No clue. Help?
\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
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
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
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
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
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
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
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
81 using System.Collections;
\r
83 using System.ComponentModel;
\r
85 namespace System.Web.UI
\r
87 public class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor
\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 private bool autoID = true;
\r
115 private DataBindingCollection dataBindings = null;
\r
119 if (this is INamingContainer) _isNamingContainer = true;
\r
121 public virtual string ClientID //DIT
\r
125 if (_cachedUserId != null && _cachedClientId != null)
\r
126 return _cachedClientId;
\r
127 _cachedUserId = UniqueID.Replace(':', '_');
\r
128 return _cachedUserId;
\r
131 public virtual ControlCollection Controls //DIT
\r
135 if (_controls == null) _controls = CreateControlCollection();
\r
139 public virtual bool EnableViewState //DIT
\r
143 return _enableViewState;
\r
147 _enableViewState = value;
\r
150 public virtual string ID
\r
158 if (value == null || value == "") return;
\r
160 _cachedUserId = null;
\r
161 //TODO: Some Naming Container stuff here I think.
\r
164 public virtual Control NamingContainer //DIT
\r
168 if (_namingContainer == null && _parent != null)
\r
170 if (_parent._isNamingContainer == false)
\r
171 _namingContainer = _parent.NamingContainer;
\r
173 _namingContainer = _parent;
\r
175 return _namingContainer;
\r
178 public virtual Page Page //DIT
\r
182 if (_page == null && _parent != null) _page = _parent.Page;
\r
190 public virtual Control Parent //DIT
\r
197 public ISite Site //DIT
\r
208 public virtual string TemplateSourceDirectory
\r
212 return Context.Request.ApplicationPath; //TODO: Dont think this is right.
\r
217 public virtual string UniqueID
\r
221 //TODO: Some Naming container methods here. What are they? Why arnt they declared?
\r
222 //Note: Nuked the old stuff here. Was total crap. :)
\r
226 public virtual bool Visible
\r
227 { //TODO: Are children visible when parents are not?
\r
237 protected bool ChildControlsCreated //DIT
\r
241 return _childControlsCreated;
\r
245 if (value == false && _childControlsCreated == true)
\r
247 _childControlsCreated = value;
\r
250 protected virtual HttpContext Context //DIT
\r
254 HttpContext context;
\r
255 if (_context != null)
\r
257 if (_parent == null)
\r
258 return HttpContext.Current;
\r
259 context = _parent.Context;
\r
260 if (context != null)
\r
262 return HttpContext.Current;
\r
265 protected EventHandlerList Events //DIT
\r
269 if (_events == null)
\r
271 _events = new EventHandlerList();
\r
276 protected bool HasChildViewState //DIT
\r
280 if (_childViewStates == null) return false;
\r
284 protected bool IsTrackingViewState //DIT
\r
288 return _trackViewState;
\r
291 protected virtual StateBag ViewState
\r
295 if(_viewState == null)
\r
297 _viewState = new StateBag(ViewStateIgnoresCase);
\r
298 if(IsTrackingViewState)
\r
299 _viewState.TrackViewState();
\r
304 protected virtual bool ViewStateIgnoresCase //DIT
\r
311 protected virtual void AddParsedSubObject(object obj) //DIT
\r
313 Control c = (Control)obj;
\r
314 if (c != null) Controls.Add(c);
\r
316 protected void BuildProfileTree(string parentId, bool calcViewState)
\r
320 protected void ClearChildViewState()
\r
323 //Not quite sure about this. an example clears children then calls this, so I think
\r
324 //view state is local to the current object, not children.
\r
326 protected virtual void CreateChildControls() {} //DIT
\r
327 protected virtual ControlCollection CreateControlCollection() //DIT
\r
329 return new ControlCollection(this);
\r
331 protected virtual void EnsureChildControls() //DIT
\r
333 if (_childControlsCreated == false)
\r
335 CreateChildControls();
\r
336 ChildControlsCreated = true;
\r
339 protected virtual Control FindControl(string id, int pathOffset)
\r
341 //TODO: I think there is Naming Container stuff here. Redo.
\r
343 for (i = pathOffset; i < _controls.Count; i++)
\r
344 if (_controls[i].ID == id) return _controls[i];
\r
347 protected virtual void LoadViewState(object savedState)
\r
349 //TODO: What should I do by default?
\r
353 protected string MapPathSecure(string virtualPath)
\r
355 //TODO: Need to read up on security+web.
\r
356 //Return the same path. So AdRotator can read its config file.
\r
357 return virtualPath;
\r
359 protected virtual bool OnBubbleEvent(object source, EventArgs args) //DIT
\r
363 protected virtual void OnDataBinding(EventArgs e) //DIT
\r
365 if (_events != null)
\r
367 EventHandler eh = (EventHandler)(_events[DataBindingEvent]);
\r
368 if (eh != null) eh(this, e);
\r
371 protected virtual void OnInit(EventArgs e) //DIT
\r
373 if (_events != null)
\r
375 EventHandler eh = (EventHandler)(_events[InitEvent]);
\r
376 if (eh != null) eh(this, e);
\r
379 protected virtual void OnLoad(EventArgs e) //DIT
\r
381 if (_events != null)
\r
383 EventHandler eh = (EventHandler)(_events[LoadEvent]);
\r
384 if (eh != null) eh(this, e);
\r
387 protected virtual void OnPreRender(EventArgs e) //DIT
\r
389 if (_events != null)
\r
391 EventHandler eh = (EventHandler)(_events[PreRenderEvent]);
\r
392 if (eh != null) eh(this, e);
\r
395 protected virtual void OnUnload(EventArgs e) //DIT
\r
397 if (_events != null)
\r
399 EventHandler eh = (EventHandler)(_events[UnloadEvent]);
\r
400 if (eh != null) eh(this, e);
\r
405 protected void RaiseBubbleEvent(object source, EventArgs args)
\r
407 throw new NotImplementedException();
\r
410 protected virtual void Render(HtmlTextWriter writer) //DIT
\r
412 RenderChildren(writer);
\r
414 protected virtual void RenderChildren(HtmlTextWriter writer) //DIT
\r
416 if (_renderMethodDelegate != null)
\r
417 _renderMethodDelegate(writer, this);
\r
418 else if (_controls != null)
\r
419 foreach (Control c in _controls)
\r
420 c.RenderControl(writer);
\r
422 protected virtual object SaveViewState()
\r
426 protected virtual void TrackViewState()
\r
428 _trackViewState = true;
\r
432 public virtual void Dispose()
\r
434 //TODO: nuke stuff.
\r
435 throw new NotImplementedException();
\r
437 if (_events != null)
\r
439 EventHandler eh = (EventHandler)(_events[DisposedEvent]);
\r
440 if (eh != null) eh(this, e);
\r
445 public bool HasChildren
\r
447 get { return (_controls != null && _controls.Count > 0); }
\r
450 public event EventHandler DataBinding //DIT
\r
454 Events.AddHandler(DataBindingEvent, value);
\r
458 Events.RemoveHandler(DataBindingEvent, value);
\r
461 public event EventHandler Disposed //DIT
\r
465 Events.AddHandler(DisposedEvent, value);
\r
469 Events.RemoveHandler(DisposedEvent, value);
\r
472 public event EventHandler Init //DIT
\r
476 Events.AddHandler(InitEvent, value);
\r
480 Events.RemoveHandler(InitEvent, value);
\r
483 public event EventHandler Load //DIT
\r
487 Events.AddHandler(LoadEvent, value);
\r
491 Events.RemoveHandler(LoadEvent, value);
\r
494 public event EventHandler PreRender //DIT
\r
498 Events.AddHandler(PreRenderEvent, value);
\r
502 Events.RemoveHandler(PreRenderEvent, value);
\r
505 public event EventHandler Unload //DIT
\r
509 Events.AddHandler(UnloadEvent, value);
\r
513 Events.RemoveHandler(UnloadEvent, value);
\r
516 public virtual void DataBind() //DIT
\r
518 OnDataBinding(EventArgs.Empty);
\r
519 if (_controls != null)
\r
520 foreach (Control c in _controls)
\r
523 public virtual Control FindControl(string id) //DIT
\r
525 return FindControl(id, 0);
\r
527 public virtual bool HasControls() //DIT
\r
529 if (_controls != null && _controls.Count >0) return true;
\r
532 public void RenderControl(HtmlTextWriter writer)
\r
536 // By now, PreRender is fired here.
\r
537 OnPreRender (EventArgs.Empty); //FIXME
\r
538 //TODO: Something about tracing here.
\r
544 public string ResolveUrl(string relativeUrl)
\r
546 return relativeUrl;
\r
548 public void SetRenderMethodDelegate(RenderMethod renderMethod) //DIT
\r
550 _renderMethodDelegate = renderMethod;
\r
552 protected void LoadRecursive()
\r
554 OnLoad(EventArgs.Empty);
\r
555 if (_controls != null) foreach (Control c in _controls) c.LoadRecursive();
\r
557 protected void UnloadRecursive(Boolean dispose)
\r
559 OnUnload(EventArgs.Empty);
\r
560 if (_controls != null) foreach (Control c in _controls) c.UnloadRecursive(dispose);
\r
561 if (dispose) Dispose();
\r
563 protected void PreRenderRecursiveInternal()
\r
565 OnPreRender(EventArgs.Empty);
\r
566 if (_controls != null) foreach (Control c in _controls) c.PreRenderRecursiveInternal();
\r
568 protected void InitRecursive(Control namingContainer)
\r
570 if (_controls != null) foreach (Control c in _controls) c.InitRecursive(namingContainer);
\r
571 OnInit(EventArgs.Empty);
\r
575 protected object SaveViewStateRecursive()
\r
577 throw new NotImplementedException();
\r
581 protected void LoadViewStateRecursive(Object savedState)
\r
583 throw new NotImplementedException();
\r
586 void IParserAccessor.AddParsedSubObject(object obj)
\r
588 this.AddParsedSubObject(obj);
\r
591 DataBindingCollection IDataBindingsAccessor.DataBindings
\r
595 if(dataBindings == null)
\r
596 dataBindings = new DataBindingCollection();
\r
597 return dataBindings;
\r
601 bool IDataBindingsAccessor.HasDataBindings
\r
605 return (dataBindings!=null && dataBindings.Count>0);
\r
609 internal bool AutoID
\r
611 get { return autoID; }
\r
612 set { autoID = value; }
\r
615 internal void PreventAutoID()
\r
620 //TODO: I think there are some needed Interface implementations to do here.
\r
621 //TODO: Find api for INamingContainer.
\r