2004-05-26 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / WebControl.cs
1 //
2 // System.Web.UI.WebControls.WebControl.cs
3 //
4 // Authors:
5 //   Gaurav Vaish (gvaish@iitk.ac.in)
6 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
7 //
8 // (C) Gaurav Vaish (2002)
9 // (C) 2003 Andreas Nahr
10 //
11
12 using System;
13 using System.Collections;
14 using System.ComponentModel;
15 using System.Web;
16 using System.Web.UI;
17 using System.Drawing;
18 using System.Collections.Specialized;
19
20 namespace System.Web.UI.WebControls
21 {
22         [PersistChildrenAttribute(false)]
23         [ParseChildrenAttribute(true)]
24         public class WebControl : Control, IAttributeAccessor
25         {
26                 HtmlTextWriterTag tagKey;
27                 AttributeCollection attributes;
28                 StateBag attributeState;
29                 Style controlStyle;
30                 bool enabled = true;
31                 string tagName;
32
33                 protected WebControl () : this (HtmlTextWriterTag.Span)
34                 {
35                 }
36
37                 public WebControl (HtmlTextWriterTag tag)
38                 {
39                         tagKey = tag;
40                 }
41
42                 protected WebControl (string tag)
43                 {
44                         tagName = tag;
45                 }
46
47                 [DefaultValue (""), Bindable (true), WebCategory ("Behavior")]
48                 [WebSysDescription ("A keyboard shortcut for the WebControl.")]\r
49                 public virtual string AccessKey\r
50                 {\r
51                         get\r
52                         {\r
53                                 object o = ViewState["AccessKey"];\r
54                                 if(o!=null)\r
55                                         return (string)o;\r
56                                 return String.Empty;\r
57                         }\r
58                         set\r
59                         {
60                                 if (value != null && value.Length > 1)
61                                         throw new ArgumentOutOfRangeException ("value");
62                                 ViewState["AccessKey"] = value;\r
63                         }\r
64                 }\r
65 \r
66                 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
67                 [WebSysDescription ("Attribute tags for the Webcontrol.")]\r
68                 public AttributeCollection Attributes\r
69                 {\r
70                         get\r
71                         {\r
72                                 if(attributes==null)\r
73                                 {\r
74                                         //FIXME: From where to get StateBag and how? I think this method is OK!\r
75                                         if(attributeState == null)\r
76                                         {\r
77                                                 attributeState = new StateBag(true);\r
78                                                 if(IsTrackingViewState)\r
79                                                 {\r
80                                                         attributeState.TrackViewState();\r
81                                                 }\r
82                                         }\r
83                                         attributes = new AttributeCollection(attributeState);\r
84                                 }\r
85                                 return attributes;\r
86                         }\r
87                 }\r
88
89                 [DefaultValue (null), Bindable (true), WebCategory ("Appearance")]
90                 [TypeConverter (typeof (WebColorConverter))]
91                 [WebSysDescription ("The background color for the WebControl.")]\r
92                 public virtual Color BackColor\r
93                 {\r
94                         get {\r
95                                 if (!ControlStyleCreated)\r
96                                         return Color.Empty;\r
97                                 return ControlStyle.BackColor;\r
98                         }\r
99 \r
100                         set {\r
101                                 ControlStyle.BackColor = value;\r
102                         }\r
103                 }\r
104
105                 [DefaultValue (null), Bindable (true), WebCategory ("Appearance")]
106                 [TypeConverter (typeof (WebColorConverter))]
107                 [WebSysDescription ("The border color for the WebControl.")]\r
108                 public virtual Color BorderColor\r
109                 {\r
110                         get {\r
111                                 if (!ControlStyleCreated)\r
112                                         return Color.Empty;\r
113                                 return ControlStyle.BorderColor;\r
114                         }\r
115 \r
116                         set {\r
117                                 ControlStyle.BorderColor = value;\r
118                         }\r
119                 }\r
120
121                 [DefaultValue (typeof(BorderStyle), "NotSet"), Bindable (true), WebCategory ("Appearance")]
122                 [WebSysDescription ("The style/type of the border used for the WebControl.")]\r
123                 public virtual BorderStyle BorderStyle\r
124                 {\r
125                         get {\r
126                                 if (!ControlStyleCreated)\r
127                                         return BorderStyle.NotSet;\r
128                                 return ControlStyle.BorderStyle;\r
129                         }\r
130 \r
131                         set {\r
132                                 ControlStyle.BorderStyle = value;\r
133                         }\r
134                 }\r
135
136                 [DefaultValue (null), Bindable (true), WebCategory ("Appearance")]
137                 [WebSysDescription ("The width of the border used for the WebControl.")]\r
138                 public virtual Unit BorderWidth\r
139                 {\r
140                         get {\r
141                                 if (!ControlStyleCreated)\r
142                                         return Unit.Empty;\r
143                                 return ControlStyle.BorderWidth;\r
144                         }\r
145 \r
146                         set {\r
147                                 if (value.Value < 0)\r
148                                         throw new ArgumentOutOfRangeException ("value");\r
149                                 ControlStyle.BorderWidth = value;\r
150                         }\r
151                 }\r
152
153                 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
154                 [WebSysDescription ("The style used to display this Webcontrol.")]\r
155                 public Style ControlStyle\r
156                 {\r
157                         get\r
158                         {\r
159                                 if(controlStyle == null)\r
160                                 {\r
161                                         controlStyle = CreateControlStyle();\r
162                                         if(IsTrackingViewState)\r
163                                         {\r
164                                                 controlStyle.TrackViewState();\r
165                                         }\r
166                                         controlStyle.LoadViewState(null);\r
167                                 }\r
168                                 return controlStyle;\r
169                         }\r
170                 }\r
171
172                 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
173                 [WebSysDescription ("Determines if a style exists for this Webcontrol.")]\r
174                 public bool ControlStyleCreated\r
175                 {\r
176                         get\r
177                         {\r
178                                 return (controlStyle!=null);\r
179                         }\r
180                 }\r
181
182                 [DefaultValue (""), Bindable (true), WebCategory ("Appearance")]
183                 [WebSysDescription ("The cascading stylesheet class that is associated with this WebControl.")]\r
184                 public virtual string CssClass\r
185                 {\r
186                         get\r
187                         {\r
188                                 return ControlStyle.CssClass;\r
189                         }\r
190                         set\r
191                         {\r
192                                 ControlStyle.CssClass = value;\r
193                         }\r
194                 }\r
195
196                 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
197                 [WebSysDescription ("The activation state of this WebControl.")]
198                 public virtual bool Enabled {
199                         get {
200                                 return enabled;
201                         }
202                         set {
203                                 if (enabled != value) {
204                                         ViewState ["Enabled"] = value;
205                                         if (IsTrackingViewState)
206                                                 EnableViewState = true;
207                                 }
208
209                                 enabled = value;
210                         }
211                 }
212
213                 [DefaultValue (null), NotifyParentProperty (true), WebCategory ("Appearance")]
214                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
215                 [WebSysDescription ("The font of this WebControl.")]\r
216                 public virtual FontInfo Font\r
217                 {\r
218                         get\r
219                         {\r
220                                 return ControlStyle.Font;\r
221                         }\r
222                 }\r
223
224                 [DefaultValue (null), Bindable (true), WebCategory ("Appearance")]
225                 [TypeConverter (typeof (WebColorConverter))]
226                 [WebSysDescription ("The color that is used to paint the primary display of the WebControl.")]\r
227                 public virtual Color ForeColor\r
228                 {\r
229                         get {\r
230                                 if (!ControlStyleCreated)\r
231                                         return Color.Empty;\r
232                                 return ControlStyle.ForeColor;\r
233                         }\r
234 \r
235                         set {\r
236                                 ControlStyle.ForeColor = value;\r
237                         }\r
238                 }\r
239
240                 [DefaultValue (null), Bindable (true), WebCategory ("Layout")]
241                 [WebSysDescription ("The height of this WebControl.")]\r
242                 public virtual Unit Height\r
243                 {\r
244                         get\r
245                         {\r
246                                 return ControlStyle.Height;\r
247                         }\r
248                         set\r
249                         {\r
250                                 if (value.Value < 0)
251                                         throw new ArgumentOutOfRangeException ("value");
252                                 ControlStyle.Height = value;\r
253                         }\r
254                 }\r
255
256                 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
257                 [WebSysDescription ("Direct access to the styles used for this Webcontrol.")]\r
258                 public CssStyleCollection Style\r
259                 {\r
260                         get\r
261                         {\r
262                                 return Attributes.CssStyle;\r
263                         }\r
264                 }\r
265
266                 [DefaultValue (0), WebCategory ("Behavior")]
267                 [WebSysDescription ("The order in which this WebControl gets tabbed through.")]\r
268                 public virtual short TabIndex\r
269                 {\r
270                         get\r
271                         {\r
272                                 object o = ViewState["TabIndex"];\r
273                                 if(o!=null)\r
274                                         return (short)o;\r
275                                 return 0;\r
276                         }\r
277                         set\r
278                         {\r
279                                 if(value < short.MinValue || value > short.MaxValue)\r
280                                         throw new ArgumentOutOfRangeException ("value");\r
281                                 ViewState["TabIndex"] = value;\r
282                         }\r
283                 }\r
284
285                 [DefaultValue (""), Bindable (true), WebCategory ("Behavior")]
286                 [WebSysDescription ("A tooltip that is shown when hovering the mouse above the WebControl.")]\r
287                 public virtual string ToolTip\r
288                 {\r
289                         get\r
290                         {\r
291                                 object o = ViewState["ToolTip"];\r
292                                 if(o!=null)\r
293                                         return (string)o;\r
294                                 return String.Empty;\r
295                         }\r
296                         set\r
297                         {\r
298                                 ViewState["ToolTip"] = value;\r
299                         }\r
300                 }\r
301
302                 [DefaultValue (null), Bindable (true), WebCategory ("Layout")]
303                 [WebSysDescription ("The width of this WebControl.")]\r
304                 public virtual Unit Width\r
305                 {\r
306                         get\r
307                         {\r
308                                 return ControlStyle.Width;\r
309                         }\r
310                         set\r
311                         {\r
312                                 if (value.Value < 0)
313                                         throw new ArgumentOutOfRangeException ("value");
314                                 ControlStyle.Width = value;\r
315                         }\r
316                 }\r
317
318                 public void ApplyStyle(Style s)
319                 {
320                         if (s != null && !s.IsEmpty)
321                                 ControlStyle.CopyFrom (s);
322                 }
323
324                 public void CopyBaseAttributes(WebControl controlSrc)\r
325                 {\r
326                         /*\r
327                          * AccessKey, Enabled, ToolTip, TabIndex, Attributes\r
328                         */\r
329                         AccessKey  = controlSrc.AccessKey;\r
330                         Enabled    = controlSrc.Enabled;\r
331                         ToolTip    = controlSrc.ToolTip;\r
332                         TabIndex   = controlSrc.TabIndex;\r
333                         AttributeCollection otherAtt = controlSrc.Attributes;\r
334                         foreach (string key in otherAtt.Keys)\r
335                                 Attributes [key] = otherAtt [key];\r
336                 }\r
337 \r
338                 public void MergeStyle(Style s)\r
339                 {\r
340                         ControlStyle.MergeWith(s);\r
341                 }\r
342 \r
343                 public virtual void RenderBeginTag(HtmlTextWriter writer)\r
344                 {\r
345                         AddAttributesToRender(writer);\r
346                         writer.RenderBeginTag(TagName);\r
347                 }\r
348 \r
349                 public virtual void RenderEndTag(HtmlTextWriter writer)\r
350                 {\r
351                         writer.RenderEndTag();\r
352                 }\r
353 \r
354                 protected virtual HtmlTextWriterTag TagKey\r
355                 {\r
356                         get\r
357                         {\r
358                                 return tagKey;\r
359                         }\r
360                 }\r
361 \r
362                 protected virtual string TagName\r
363                 {\r
364                         get\r
365                         {\r
366                                 if(tagName == null && TagKey != 0)\r
367                                 {\r
368                                         tagName = Enum.Format(typeof(HtmlTextWriterTag), TagKey, "G").ToString();\r
369                                 }\r
370                                 // What if tagName is null and tagKey 0?\r
371                                 return tagName;\r
372                         }\r
373                 }\r
374 \r
375                 protected virtual void AddAttributesToRender(HtmlTextWriter writer)\r
376                 {\r
377                         if(ID!=null)\r
378                         {\r
379                                 writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);\r
380                         }\r
381                         if(AccessKey.Length>0)\r
382                         {\r
383                                 writer.AddAttribute(HtmlTextWriterAttribute.Accesskey, AccessKey);\r
384                         }\r
385                         if(!Enabled)\r
386                         {\r
387                                 writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");\r
388                         }\r
389                         if(ToolTip.Length>0)\r
390                         {\r
391                                 writer.AddAttribute(HtmlTextWriterAttribute.Title, ToolTip);\r
392                         }\r
393                         if(TabIndex != 0)\r
394                         {\r
395                                 writer.AddAttribute(HtmlTextWriterAttribute.Tabindex, TabIndex.ToString());\r
396                         }\r
397                         if(ControlStyleCreated)\r
398                         {\r
399                                 if(!ControlStyle.IsEmpty)\r
400                                 {\r
401                                         ControlStyle.AddAttributesToRender(writer, this);\r
402                                 }\r
403                         }\r
404                         if(attributeState != null){\r
405                                 IEnumerator ie = Attributes.Keys.GetEnumerator ();\r
406                                 while (ie.MoveNext ()){\r
407                                         string key = (string) ie.Current;\r
408                                         writer.AddAttribute (key, Attributes [key]);\r
409                                 }\r
410                         }\r
411                 }\r
412
413                 protected virtual Style CreateControlStyle ()
414                 {
415                         return new Style (ViewState);
416                 }
417
418                 protected override void LoadViewState (object savedState)
419                 {
420                         if (savedState == null)
421                                 return;
422
423                         Pair saved = (Pair) savedState;
424                         base.LoadViewState (saved.First);
425                         
426                         if (ControlStyleCreated || ViewState [System.Web.UI.WebControls.Style.selectionBitString] != null)
427                                 ControlStyle.LoadViewState (null);
428
429                         if (saved.Second != null)
430                         {
431                                 attributeState = new StateBag(true);
432                                 attributeState.TrackViewState();
433                                 attributeState.LoadViewState (saved.Second);
434                         }\r
435                         \r
436                         object enable = ViewState["Enabled"];\r
437                         if (enable!=null)\r
438                         {\r
439                                 Enabled = (bool)enable;\r
440                                 EnableViewState = true; \r
441                         }
442                 }
443
444                 protected override void Render(HtmlTextWriter writer)
445                 {
446                         RenderBeginTag (writer);
447                         RenderContents (writer);
448                         RenderEndTag (writer);
449                 }
450
451                 protected virtual void RenderContents(HtmlTextWriter writer)
452                 {
453                         base.Render (writer);
454                 }
455
456                 protected override object SaveViewState()
457                 {\r
458                         if (EnableViewState)\r
459                                 ViewState["Enabled"] = enabled;
460                         if (ControlStyleCreated)
461                                 ControlStyle.SaveViewState ();
462                         
463                         object baseView = base.SaveViewState ();
464                         object attrView = null;
465                         if (attributeState != null)
466                                 attrView = attributeState.SaveViewState ();
467                         
468                         if (baseView == null && attrView == null)
469                                 return null;
470
471                         return new Pair (baseView, attrView);
472                 }
473
474                 protected override void TrackViewState()
475                 {
476                         base.TrackViewState();
477                         if (ControlStyleCreated)
478                                 ControlStyle.TrackViewState ();
479                         if (attributeState != null)
480                                 attributeState.TrackViewState ();
481                 }
482
483                 string IAttributeAccessor.GetAttribute(string key)
484                 {
485                         if (attributes != null)
486                                 return Attributes [key] as string;
487
488                         return null;
489                 }
490
491                 void IAttributeAccessor.SetAttribute(string key, string value)
492                 {
493                         Attributes [key] = value;
494                 }
495         }
496 }
497