68248440e4aa4f6414bf7e894fb7cda415b906e8
[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                 UpdatePanelRenderMode _renderMode = UpdatePanelRenderMode.Block;
54                 ScriptManager _scriptManager;
55
56                 [Category ("Behavior")]
57                 [DefaultValue (true)]
58                 public bool ChildrenAsTriggers {
59                         get {
60                                 return _childrenAsTriggers;
61                         }
62                         set {
63                                 _childrenAsTriggers = value;
64                         }
65                 }
66
67                 [TemplateInstance (TemplateInstance.Single)]
68                 [PersistenceMode (PersistenceMode.InnerProperty)]
69                 [Browsable (false)]
70                 public ITemplate ContentTemplate {
71                         get {
72                                 return _contentTemplate;
73                         }
74                         set {
75                                 _contentTemplate = value;
76                         }
77                 }
78
79                 [Browsable (false)]
80                 public Control ContentTemplateContainer {
81                         get {
82                                 if (_contentTemplateContainer == null) {
83                                         _contentTemplateContainer = CreateContentTemplateContainer ();
84                                         Controls.Add (_contentTemplateContainer);
85                                 }
86                                 return _contentTemplateContainer;
87                         }
88                 }
89
90                 public override sealed ControlCollection Controls {
91                         get {
92                                 return base.Controls;
93                         }
94                 }
95
96                 [Browsable (false)]
97                 public bool IsInPartialRendering {
98                         get {
99                                 return ScriptManager.IsInPartialRendering;
100                         }
101                 }
102
103                 [Category ("Layout")]
104                 public UpdatePanelRenderMode RenderMode {
105                         get {
106                                 return _renderMode;
107                         }
108                         set {
109                                 _renderMode = value;
110                         }
111                 }
112
113                 protected internal virtual bool RequiresUpdate {
114                         get {
115                                 return UpdateMode == UpdatePanelUpdateMode.Always || _requiresUpdate;
116                         }
117                 }
118
119                 internal ScriptManager ScriptManager {
120                         get {
121                                 if (_scriptManager == null) {
122                                         _scriptManager = ScriptManager.GetCurrent (Page);
123                                         if (_scriptManager == null)
124                                                 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));
125                                 }
126                                 return _scriptManager;
127                         }
128                 }
129
130                 [MergableProperty (false)]
131                 [DefaultValue ("")]
132                 [PersistenceMode (PersistenceMode.InnerProperty)]
133                 [Category ("Behavior")]
134                 public UpdatePanelTriggerCollection Triggers {
135                         get {
136                                 if (_triggers == null)
137                                         _triggers = new UpdatePanelTriggerCollection (this);
138                                 return _triggers;
139                         }
140                 }
141
142                 [Category ("Behavior")]
143                 [DefaultValueAttribute (UpdatePanelUpdateMode.Always)]
144                 public UpdatePanelUpdateMode UpdateMode {
145                         get {
146                                 return _updateMode;
147                         }
148                         set {
149                                 _updateMode = value;
150                         }
151                 }
152
153                 protected virtual Control CreateContentTemplateContainer () {
154                         return new Control ();
155                 }
156
157                 [MonoTODO ()]
158                 protected override sealed ControlCollection CreateControlCollection () {
159                         // TODO: Because this method is protected and sealed, it is visible to classes that inherit 
160                         // from the UpdatePanel class, but it cannot be overridden. This method overrides 
161                         // the base implementation to return a specialized ControlCollection object that throws 
162                         // an InvalidOperationException when the Add(Control), AddAt(Int32, Control), Clear(), 
163                         // Remove(Control), or RemoveAt(Int32) method of the ControlCollection class is invoked. 
164                         // To change the content of the UpdatePanel control, modify the child controls of 
165                         // the ContentTemplateContainer property.
166
167                         return base.CreateControlCollection ();
168                 }
169
170                 protected internal virtual void Initialize () {
171                         if (_triggers != null) {
172                                 for (int i = 0; i < _triggers.Count; i++) {
173                                         _triggers [i].Initialize ();
174                                 }
175                         }
176                 }
177
178                 protected internal override void OnInit (EventArgs e) {
179                         base.OnInit (e);
180
181                         ScriptManager.RegisterUpdatePanel (this);
182
183                         if (ContentTemplate != null)
184                                 ContentTemplate.InstantiateIn (ContentTemplateContainer);
185                 }
186
187                 protected internal override void OnLoad (EventArgs e) {
188                         base.OnLoad (e);
189
190                         Initialize ();
191                 }
192
193                 protected internal override void OnPreRender (EventArgs e) {
194                         base.OnPreRender (e);
195
196                         if (UpdateMode == UpdatePanelUpdateMode.Always && !ChildrenAsTriggers)
197                                 throw new InvalidOperationException (String.Format ("ChildrenAsTriggers cannot be set to false when UpdateMode is set to Always on UpdatePanel '{0}'", ID));
198                 }
199
200                 protected internal override void OnUnload (EventArgs e) {
201                         base.OnUnload (e);
202                 }
203
204                 protected internal override void Render (HtmlTextWriter writer) {
205                         writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID);
206                         if (RenderMode == UpdatePanelRenderMode.Block)
207                                 writer.RenderBeginTag (HtmlTextWriterTag.Div);
208                         else
209                                 writer.RenderBeginTag (HtmlTextWriterTag.Span);
210                         RenderChildren (writer);
211                         writer.RenderEndTag ();
212                 }
213
214                 protected internal override void RenderChildren (HtmlTextWriter writer) {
215                         if (ScriptManager.IsInAsyncPostBack){
216                                 if (RequiresUpdate && !ScriptManager.IsInPartialRendering) {
217                                         ScriptManager.IsInPartialRendering = true;
218                                         HtmlTextWriter responseOutput = ((ScriptManager.AlternativeHtmlTextWriter) writer).ResponseOutput;
219                                         StringBuilder sb = new StringBuilder ();
220                                         HtmlTextWriter w = new HtmlTextWriter (new StringWriter (sb));
221                                         base.RenderChildren (w);
222                                         w.Flush ();
223
224                                         ScriptManager.WriteCallbackPanel (responseOutput, this, sb);
225
226                                         ScriptManager.IsInPartialRendering = false;
227                                 }
228                                 else {
229                                         if (ScriptManager.IsInPartialRendering)
230                                                 ScriptManager.RegisterChildUpdatePanel (this);
231                                         base.RenderChildren (writer);
232                                 }
233                         }
234                         else
235                                 base.RenderChildren (writer);
236                 }
237
238                 public void Update () {
239                         _requiresUpdate = true;
240                 }
241         }
242 }