2006-02-21 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / CheckBox.cs
1 //
2 // System.Web.UI.WebControls.CheckBox.cs
3 //
4 // Author:
5 //      Dick Porter  <dick@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System.Collections.Specialized;
30 using System.ComponentModel;
31 using System.Globalization;
32 using System.Security.Permissions;
33
34 namespace System.Web.UI.WebControls {
35         // CAS
36         [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
37         [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
38         // attributes
39         [Designer ("System.Web.UI.Design.WebControls.CheckBoxDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
40         [DataBindingHandler ("System.Web.UI.Design.TextDataBindingHandler, " + Consts.AssemblySystem_Design)]
41         [DefaultEvent ("CheckedChanged")]
42         [DefaultProperty ("Text")]
43 #if NET_2_0
44         [ControlValueProperty ("Checked", null)]
45         [SupportsEventValidation]
46 #endif          
47         public class CheckBox : WebControl, IPostBackDataHandler
48 #if NET_2_0
49         , ICheckBoxControl
50 #endif
51         {
52                 string render_type;
53
54 #if NET_2_0
55                 AttributeCollection inputAttributes;
56                 StateBag inputAttributesState;
57                 AttributeCollection labelAttributes;
58                 StateBag labelAttributesState;
59 #endif
60                 
61                 public CheckBox () : base (HtmlTextWriterTag.Input)
62                 {
63                         render_type = "checkbox";
64                 }
65
66                 internal CheckBox (string render_type) : base (HtmlTextWriterTag.Input)
67                 {
68                         this.render_type = render_type;
69                 }
70
71                 [DefaultValue (false)]
72 #if NET_2_0
73                 [Themeable (false)]
74 #endif          
75                 [WebSysDescription ("")]
76                 [WebCategory ("Behavior")]
77                 public virtual bool AutoPostBack 
78                 {
79                         get {
80                                 return (ViewState.GetBool ("AutoPostBack",
81                                                            false));
82                         }
83                         set {
84                                 ViewState["AutoPostBack"] = value;
85                         }
86                 }
87
88 #if NET_2_0
89                 [DefaultValue (false)]
90                 [Themeable (false)]
91                 [MonoTODO]
92                 [WebSysDescription ("")]
93                 [WebCategory ("Behavior")]
94                 public virtual bool CausesValidation 
95                 {
96                         get { return ViewState.GetBool ("CausesValidation", false); }
97                         set { ViewState ["CausesValidation"] = value; }
98                 }
99 #endif          
100                 
101
102                 [DefaultValue (false)]
103 #if NET_2_0
104                 [Bindable (true, BindingDirection.TwoWay)]
105                 [Themeable (false)]
106 #else           
107                 [Bindable (true)]
108 #endif          
109                 [WebSysDescription ("")]
110                 [WebCategory ("Behavior")]
111                 public virtual bool Checked 
112                 {
113                         get {
114                                 return (ViewState.GetBool ("Checked", false));
115                         }
116                         set {
117                                 ViewState["Checked"] = value;
118                         }
119                 }
120
121 #if NET_2_0
122                 [Browsable (false)]
123                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
124                 public AttributeCollection InputAttributes 
125                 {
126                         get {
127                                 if (inputAttributes == null) {
128                                         if (inputAttributesState == null) {
129                                                 inputAttributesState = new StateBag (true);
130                                                 if (IsTrackingViewState)
131                                                         inputAttributesState.TrackViewState();
132                                         }
133                                         inputAttributes = new AttributeCollection (inputAttributesState);
134                                 }
135                                 return inputAttributes;
136                         }
137                 }
138
139                 [Browsable (false)]
140                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
141                 public AttributeCollection LabelAttributes
142                 {
143                         get {
144                                 if (labelAttributes == null) {
145                                         if (labelAttributesState == null) {
146                                                 labelAttributesState = new StateBag (true);
147                                                 if (IsTrackingViewState)
148                                                         labelAttributesState.TrackViewState();
149                                         }
150                                         labelAttributes = new AttributeCollection (labelAttributesState);
151                                 }
152                                 return labelAttributes;
153                         }
154                 }
155 #endif          
156
157                 [DefaultValue ("")]
158                 [Bindable (true)]
159 #if NET_2_0
160                 [Localizable (true)]
161 #endif          
162                 [WebSysDescription ("")]
163                 [WebCategory ("Appearance")]
164                 public virtual string Text 
165                 {
166                         get {
167                                 return (ViewState.GetString ("Text",
168                                                              String.Empty));
169                         }
170                         set {
171                                 ViewState["Text"] = value;
172                         }
173                 }
174
175                 [DefaultValue (TextAlign.Right)]
176 #if ONLY_1_1
177                 [Bindable (true)]
178 #endif          
179                 [WebSysDescription ("")]
180                 [WebCategory ("Appearance")]
181                 public virtual TextAlign TextAlign
182                 {
183                         get { return (TextAlign) ViewState.GetInt ("TextAlign", (int)TextAlign.Right); }
184                         set {
185                                 if (value != TextAlign.Left &&
186                                     value != TextAlign.Right) {
187                                         throw new ArgumentOutOfRangeException ("value");
188                                 }
189                                 
190                                 ViewState["TextAlign"] = value;
191                         }
192                 }
193
194 #if NET_2_0
195                 [Themeable (false)]
196                 [DefaultValue ("")]
197                 [WebSysDescription ("")]
198                 [WebCategoryAttribute ("Behavior")]
199                 public string ValidationGroup
200                 {
201                         get { return ViewState.GetString ("ValidationGroup", String.Empty); }
202                         set { ViewState["ValidationGroup"] = value; }
203                 }
204 #endif          
205
206                 private static readonly object EventCheckedChanged = new object ();
207                 [WebSysDescription ("")]
208                 [WebCategory ("Action")]
209                 public event EventHandler CheckedChanged 
210                 {
211                         add {
212                                 Events.AddHandler (EventCheckedChanged, value);
213                         }
214                         remove {
215                                 Events.RemoveHandler (EventCheckedChanged, value);
216                         }
217                 }
218
219                 protected virtual void OnCheckedChanged (EventArgs e)
220                 {
221                         EventHandler handler = (EventHandler)Events[EventCheckedChanged];
222                         
223                         if (handler != null) {
224                                 handler (this, e);
225                         }
226                 }
227
228                 internal virtual string NameAttribute 
229                 {
230                         get {
231                                 return (this.UniqueID);
232                         }
233                 }
234                 
235 #if NET_2_0
236                 protected override void LoadViewState (object savedState)
237                 {
238                         if (savedState == null) {
239                                 base.LoadViewState (null);
240                                 return;
241                         }
242
243                         Triplet saved = (Triplet) savedState;
244                         base.LoadViewState (saved.First);
245
246                         if (saved.Second != null) {
247                                 if (inputAttributesState == null) {
248                                         inputAttributesState = new StateBag(true);
249                                         inputAttributesState.TrackViewState ();
250                                 }
251                                 inputAttributesState.LoadViewState (saved.Second);
252                         }
253
254                         if (saved.Third != null) {
255                                 if (labelAttributesState == null) {
256                                         labelAttributesState = new StateBag(true);
257                                         labelAttributesState.TrackViewState ();
258                                 }
259                                 labelAttributesState.LoadViewState (saved.Third);
260                         }
261                 }
262
263                 protected override object SaveViewState ()
264                 {
265                         object baseView = base.SaveViewState ();
266                         object inputAttrView = null;
267                         object labelAttrView = null;
268
269                         if (inputAttributesState != null)
270                                 inputAttrView = inputAttributesState.SaveViewState ();
271
272                         if (labelAttributesState != null)
273                                 labelAttrView = labelAttributesState.SaveViewState ();
274
275                         if (baseView == null && inputAttrView == null && labelAttrView == null)
276                                 return null;
277
278                         return new Triplet (baseView, inputAttrView, labelAttrView);            
279                 }
280
281                 protected override void TrackViewState ()
282                 {
283                         base.TrackViewState();
284                         if (inputAttributesState != null)
285                                 inputAttributesState.TrackViewState ();
286                         if (labelAttributesState != null)
287                                 labelAttributesState.TrackViewState ();
288                 }
289 #endif          
290
291 #if NET_2_0
292                 protected internal
293 #else           
294                 protected
295 #endif          
296                 override void OnPreRender (EventArgs e)
297                 {
298                         base.OnPreRender (e);
299
300                         if (Page != null) {
301                                 Page.RegisterRequiresPostBack (this);
302                         }
303                 }
304
305 #if NET_2_0
306                 protected internal
307 #else           
308                 protected
309 #endif          
310                 override void Render (HtmlTextWriter w)
311                 {
312                         if (Page != null)
313                                 Page.VerifyRenderingInServerForm (this);
314
315                         bool need_span = ControlStyleCreated && !ControlStyle.IsEmpty;
316                         if (need_span)
317                                 ControlStyle.AddAttributesToRender (w, this);
318
319                         if (!Enabled) {
320                                 w.AddAttribute (HtmlTextWriterAttribute.Disabled, "disabled");
321                                 need_span = true;
322                         }
323
324                         string tt = ToolTip;
325                         if (tt != ""){
326                                 w.AddAttribute ("title", tt);
327                                 need_span = true;
328                         }
329
330                         if (Attributes.Count > 0){
331                                 Attributes.AddAttributes (w);
332                                 need_span = true;
333                         }
334
335                         if (need_span)
336                                 w.RenderBeginTag (HtmlTextWriterTag.Span);
337
338                         TextAlign align = TextAlign;
339                         if (align == TextAlign.Right) {
340                                 w.AddAttribute (HtmlTextWriterAttribute.Id, ClientID);
341                                 w.AddAttribute (HtmlTextWriterAttribute.Type, render_type);
342                                 w.AddAttribute (HtmlTextWriterAttribute.Name, NameAttribute);
343                                 InternalAddAttributesToRender (w);
344                                 if (Checked)
345                                         w.AddAttribute (HtmlTextWriterAttribute.Checked, "checked");
346
347                                 if (AutoPostBack){
348                                         w.AddAttribute (HtmlTextWriterAttribute.Onclick,
349                                                         Page.ClientScript.GetPostBackEventReference (this, String.Empty));
350                                         w.AddAttribute ("language", "javascript");
351                                 }
352
353                                 if (AccessKey.Length > 0)
354                                         w.AddAttribute (HtmlTextWriterAttribute.Accesskey, AccessKey);
355
356                                 if (TabIndex != 0)
357                                         w.AddAttribute (HtmlTextWriterAttribute.Tabindex,
358                                                              TabIndex.ToString (CultureInfo.InvariantCulture));
359
360                                 w.RenderBeginTag (HtmlTextWriterTag.Input);
361                                 w.RenderEndTag ();
362                                 string text = Text;
363                                 if (text != "") {
364 #if NET_2_0
365                                         if (labelAttributes != null)
366                                                 labelAttributes.AddAttributes (w);
367 #endif
368                                         w.AddAttribute (HtmlTextWriterAttribute.For, ClientID);
369                                         w.RenderBeginTag (HtmlTextWriterTag.Label);
370                                         w.Write (text);
371                                         w.RenderEndTag ();
372                                 }
373                         } else {
374                                 string text = Text;
375                                 if (text != "") {
376 #if NET_2_0
377                                         if (labelAttributes != null)
378                                                 labelAttributes.AddAttributes (w);
379 #endif
380                                         w.AddAttribute (HtmlTextWriterAttribute.For, ClientID);
381                                         w.RenderBeginTag (HtmlTextWriterTag.Label);
382                                         w.Write (text);
383                                         w.RenderEndTag ();
384                                 }
385
386                                 w.AddAttribute (HtmlTextWriterAttribute.Id, ClientID);
387                                 w.AddAttribute (HtmlTextWriterAttribute.Type, render_type);
388                                 w.AddAttribute (HtmlTextWriterAttribute.Name, NameAttribute);
389                                 InternalAddAttributesToRender (w);
390                                 if (Checked)
391                                         w.AddAttribute (HtmlTextWriterAttribute.Checked, "checked");
392
393                                 if (AutoPostBack){
394                                         w.AddAttribute (HtmlTextWriterAttribute.Onclick,
395                                                         Page.ClientScript.GetPostBackEventReference (this, String.Empty));
396                                         w.AddAttribute ("language", "javascript");
397                                 }
398
399                                 if (AccessKey.Length > 0)
400                                         w.AddAttribute (HtmlTextWriterAttribute.Accesskey, AccessKey);
401
402                                 if (TabIndex != 0)
403                                         w.AddAttribute (HtmlTextWriterAttribute.Tabindex,
404                                                              TabIndex.ToString (NumberFormatInfo.InvariantInfo));
405
406                                 w.RenderBeginTag (HtmlTextWriterTag.Input);
407                                 w.RenderEndTag ();
408                         }
409
410                         if (need_span)
411                                 w.RenderEndTag ();
412                 }
413
414 #if NET_2_0
415                 protected virtual
416 #endif
417                 bool LoadPostData (string postDataKey, NameValueCollection postCollection)
418                 {
419                         string postedValue = postCollection[postDataKey];
420                         bool postedBool = ((postedValue != null) &&
421                                            (postedValue.Length > 0));
422                         
423                         if (Checked != postedBool) {
424                                 Checked = postedBool;
425                                 return (true);
426                         }
427
428                         return (false);
429                 }
430
431 #if NET_2_0
432                 protected virtual
433 #endif
434                 void RaisePostDataChangedEvent ()
435                 {
436 #if NET_2_0
437                         if (CausesValidation)
438                                 Page.Validate (ValidationGroup);
439 #endif
440                         OnCheckedChanged (EventArgs.Empty);
441                 }
442
443                 bool IPostBackDataHandler.LoadPostData (string postDataKey, NameValueCollection postCollection)
444                 {
445                         return LoadPostData (postDataKey, postCollection);
446                 }
447                 
448                 void IPostBackDataHandler.RaisePostDataChangedEvent ()
449                 {
450                         RaisePostDataChangedEvent ();
451                 }
452
453 #if NET_2_0
454                 protected override void AddAttributesToRender (HtmlTextWriter writer)
455                 {
456                         base.AddAttributesToRender (writer);
457                 }
458 #endif
459
460                 internal virtual void InternalAddAttributesToRender (HtmlTextWriter w)
461                 {
462                         if (!Enabled)
463                                 w.AddAttribute (HtmlTextWriterAttribute.Disabled, "disabled");
464                 }
465         }
466 }