support scenario, when Update panel is created programmatically
[mono.git] / mcs / class / System.Web.Extensions / System.Web.UI / UpdatePanel.cs
1 //
2 // UpdatePanel.cs
3 //
4 // Author:
5 //   Igor Zelmanovich <igorz@mainsoft.com>
6 //
7 // (C) 2007 Mainsoft, Inc.  http://www.mainsoft.com
8 //
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System;
31 using System.Collections.Generic;
32 using System.Text;
33 using System.ComponentModel;
34 using System.Security.Permissions;
35 using System.IO;
36
37 namespace System.Web.UI
38 {
39         [DesignerAttribute ("System.Web.UI.Design.UpdatePanelDesigner, System.Web.Extensions.Design, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")]
40         [DefaultPropertyAttribute ("Triggers")]
41         [ParseChildrenAttribute (true)]
42         [PersistChildrenAttribute (false)]
43         [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
44         [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
45         public class UpdatePanel : Control
46         {
47                 ITemplate _contentTemplate;
48                 Control _contentTemplateContainer;
49                 UpdatePanelUpdateMode _updateMode = UpdatePanelUpdateMode.Always;
50                 bool _childrenAsTriggers = true;
51                 bool _requiresUpdate = false;
52                 UpdatePanelTriggerCollection _triggers;
53
54                 [Category ("Behavior")]
55                 [DefaultValue (true)]
56                 public bool ChildrenAsTriggers {
57                         get {
58                                 return _childrenAsTriggers;
59                         }
60                         set {
61                                 _childrenAsTriggers = value;
62                         }
63                 }
64
65                 [TemplateInstance (TemplateInstance.Single)]
66                 [PersistenceMode (PersistenceMode.InnerProperty)]
67                 [Browsable (false)]
68                 public ITemplate ContentTemplate {
69                         get {
70                                 return _contentTemplate;
71                         }
72                         set {
73                                 _contentTemplate = value;
74                         }
75                 }
76
77                 [Browsable (false)]
78                 public Control ContentTemplateContainer {
79                         get {
80                                 if (_contentTemplateContainer == null) {
81                                         _contentTemplateContainer = CreateContentTemplateContainer ();
82                                         Controls.Add (_contentTemplateContainer);
83                                 }
84                                 return _contentTemplateContainer;
85                         }
86                 }
87
88                 public override sealed ControlCollection Controls {
89                         get {
90                                 return base.Controls;
91                         }
92                 }
93
94                 [Browsable (false)]
95                 public bool IsInPartialRendering {
96                         get {
97                                 throw new NotImplementedException ();
98                         }
99                 }
100
101                 [Category ("Layout")]
102                 public UpdatePanelRenderMode RenderMode {
103                         get {
104                                 throw new NotImplementedException ();
105                         }
106                         set {
107                                 throw new NotImplementedException ();
108                         }
109                 }
110
111                 protected internal virtual bool RequiresUpdate {
112                         get {
113                                 return UpdateMode == UpdatePanelUpdateMode.Always || _requiresUpdate;
114                         }
115                 }
116
117                 internal ScriptManager ScriptManager {
118                         get {
119                                 ScriptManager manager = ScriptManager.GetCurrent (Page);
120                                 if (manager == null)
121                                         throw new InvalidOperationException (String.Format ("The control with ID '{0}' requires a ScriptManager on the page. The ScriptManager must appear before any controls that need it.", ID));
122                                 return manager;
123                         }
124                 }
125
126                 [MergableProperty (false)]
127                 [DefaultValue ("")]
128                 [PersistenceMode (PersistenceMode.InnerProperty)]
129                 [Category ("Behavior")]
130                 public UpdatePanelTriggerCollection Triggers {
131                         get {
132                                 if (_triggers == null)
133                                         _triggers = new UpdatePanelTriggerCollection (this);
134                                 return _triggers;
135                         }
136                 }
137
138                 [Category ("Behavior")]
139                 [DefaultValueAttribute (UpdatePanelUpdateMode.Always)]
140                 public UpdatePanelUpdateMode UpdateMode {
141                         get {
142                                 return _updateMode;
143                         }
144                         set {
145                                 _updateMode = value;
146                         }
147                 }
148
149                 protected virtual Control CreateContentTemplateContainer () {
150                         return new Control ();
151                 }
152
153                 [MonoTODO ()]
154                 protected override sealed ControlCollection CreateControlCollection () {
155                         // TODO: Because this method is protected and sealed, it is visible to classes that inherit 
156                         // from the UpdatePanel class, but it cannot be overridden. This method overrides 
157                         // the base implementation to return a specialized ControlCollection object that throws 
158                         // an InvalidOperationException when the Add(Control), AddAt(Int32, Control), Clear(), 
159                         // Remove(Control), or RemoveAt(Int32) method of the ControlCollection class is invoked. 
160                         // To change the content of the UpdatePanel control, modify the child controls of 
161                         // the ContentTemplateContainer property.
162
163                         return base.CreateControlCollection ();
164                 }
165
166                 protected internal virtual void Initialize () {
167                         if (_triggers != null) {
168                                 for (int i = 0; i < _triggers.Count; i++) {
169                                         _triggers [i].Initialize ();
170                                 }
171                         }
172                 }
173
174                 protected override void OnInit (EventArgs e) {
175                         base.OnInit (e);
176
177                         ScriptManager.RegisterUpdatePanel (this);
178
179                         if (ContentTemplate != null)
180                                 ContentTemplate.InstantiateIn (ContentTemplateContainer);
181                 }
182
183                 protected override void OnLoad (EventArgs e) {
184                         base.OnLoad (e);
185
186                         Initialize ();
187                 }
188
189                 protected override void OnPreRender (EventArgs e) {
190                         base.OnPreRender (e);
191
192                         if (UpdateMode == UpdatePanelUpdateMode.Always && !ChildrenAsTriggers)
193                                 throw new InvalidOperationException (String.Format ("ChildrenAsTriggers cannot be set to false when UpdateMode is set to Always on UpdatePanel '{0}'", ID));
194                 }
195
196                 protected override void OnUnload (EventArgs e) {
197                         base.OnUnload (e);
198                 }
199
200                 protected override void Render (HtmlTextWriter writer) {
201                         writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID);
202                         writer.RenderBeginTag (HtmlTextWriterTag.Div);
203                         RenderChildren (writer);
204                         writer.RenderEndTag ();
205                 }
206
207                 protected override void RenderChildren (HtmlTextWriter writer) {
208                         if (ScriptManager.IsInAsyncPostBack && RequiresUpdate && writer is ScriptManager.AlternativeHtmlTextWriter) {
209                                 HtmlTextWriter responseOutput = ((ScriptManager.AlternativeHtmlTextWriter) writer).ResponseOutput;
210                                 StringBuilder sb = new StringBuilder ();
211                                 HtmlTextWriter w = new HtmlTextWriter (new StringWriter (sb));
212                                 base.RenderChildren (w);
213                                 w.Flush ();
214
215                                 ScriptManager.WriteCallbackPanel (responseOutput, ClientID, sb);
216                                 for (int i = 0; i < sb.Length; i++)
217                                         writer.Write (sb [i]);
218                         }
219                         else
220                                 base.RenderChildren (writer);
221                 }
222
223                 public void Update () {
224                         _requiresUpdate = true;
225                 }
226         }
227 }