1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
23 // Peter Bartok (pbartok@novell.com)
26 using System.Collections.Generic;
27 using System.ComponentModel;
29 using System.Security.Permissions;
31 namespace System.Web.UI.WebControls {
34 [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
35 [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
37 [ParseChildren (true)]
38 [PersistChildrenAttribute (false, false)]
40 public class WebControl : Control, IAttributeAccessor
42 const string DEFAULT_DISABLED_CSS_CLASS = "aspNetDisabled";
44 HtmlTextWriterTag tag;
46 AttributeCollection attributes;
47 StateBag attribute_state;
49 bool track_enabled_state;
52 DisabledCssClass = DEFAULT_DISABLED_CSS_CLASS;
54 public WebControl (HtmlTextWriterTag tag)
60 protected WebControl () : this (HtmlTextWriterTag.Span)
64 protected WebControl (string tag)
66 this.tag = HtmlTextWriterTag.Unknown;
75 [WebSysDescription ("")]
76 [WebCategory ("Behavior")]
77 public virtual string AccessKey {
79 return ViewState.GetString ("AccessKey", string.Empty);
82 if (value == null || value.Length < 2)
83 ViewState ["AccessKey"] = value;
85 throw new ArgumentException ("AccessKey can only be null, empty or a single character", "value");
90 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
91 [WebSysDescription ("")]
92 [WebCategory ("Behavior")]
93 public AttributeCollection Attributes {
95 if (attributes == null) {
96 attribute_state = new StateBag (true);
97 if (IsTrackingViewState)
98 attribute_state.TrackViewState ();
100 attributes = new AttributeCollection (attribute_state);
109 [DefaultValue(typeof (Color), "")]
110 [TypeConverter(typeof(System.Web.UI.WebControls.WebColorConverter))]
111 [WebSysDescription ("")]
112 [WebCategory ("Appearance")]
113 public virtual Color BackColor {
118 return style.BackColor;
121 ControlStyle.BackColor = value;
128 [DefaultValue(typeof (Color), "")]
129 [TypeConverter(typeof(System.Web.UI.WebControls.WebColorConverter))]
130 [WebSysDescription ("")]
131 [WebCategory ("Appearance")]
132 public virtual Color BorderColor {
137 return style.BorderColor;
141 ControlStyle.BorderColor = value;
148 [DefaultValue(BorderStyle.NotSet)]
149 [WebSysDescription ("")]
150 [WebCategory ("Appearance")]
151 public virtual BorderStyle BorderStyle {
154 return BorderStyle.NotSet;
156 return style.BorderStyle;
159 if (value < BorderStyle.NotSet || value > BorderStyle.Outset)
160 throw new ArgumentOutOfRangeException ("value");
162 ControlStyle.BorderStyle = value;
169 [DefaultValue(typeof (Unit), "")]
170 [WebSysDescription ("")]
171 [WebCategory ("Appearance")]
172 public virtual Unit BorderWidth {
177 return style.BorderWidth;
179 set { ControlStyle.BorderWidth = value; }
183 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
184 [WebSysDescription ("")]
185 [WebCategory ("Appearance")]
186 public Style ControlStyle {
189 style = this.CreateControlStyle ();
191 if (IsTrackingViewState)
192 style.TrackViewState ();
200 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
201 [EditorBrowsable (EditorBrowsableState.Never)]
202 public bool ControlStyleCreated {
204 return style != null;
210 [WebSysDescription ("")]
211 [WebCategory ("Appearance")]
212 public virtual string CssClass {
217 return style.CssClass;
220 ControlStyle.CssClass = value;
227 public virtual bool Enabled {
233 if (enabled != value) {
234 if (IsTrackingViewState)
235 track_enabled_state = true;
242 public virtual new bool EnableTheming
244 get { return base.EnableTheming; }
245 set { base.EnableTheming = value; }
251 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
252 [NotifyParentProperty(true)]
253 [WebSysDescription ("")]
254 [WebCategory ("Appearance")]
255 public virtual FontInfo Font {
257 // Oddly enough, it looks like we have to let it create the style
258 // since we can't create a FontInfo without a style owner
259 return ControlStyle.Font;
266 [DefaultValue(typeof (Color), "")]
267 [TypeConverter(typeof(System.Web.UI.WebControls.WebColorConverter))]
268 [WebSysDescription ("")]
269 [WebCategory ("Appearance")]
270 public virtual Color ForeColor {
275 return style.ForeColor;
278 ControlStyle.ForeColor = value;
283 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
288 return (attributes != null && attributes.Count > 0);
295 [DefaultValue(typeof (Unit), "")]
296 [WebSysDescription ("")]
297 [WebCategory ("Layout")]
298 public virtual Unit Height {
306 ControlStyle.Height = value;
311 public virtual new string SkinID
313 get { return base.SkinID; }
314 set { base.SkinID = value; }
318 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
319 [WebSysDescription ("")]
320 [WebCategory ("Style")]
321 public CssStyleCollection Style {
323 return Attributes.CssStyle;
327 [DefaultValue((short)0)]
328 [WebSysDescription ("")]
329 [WebCategory ("Behavior")]
330 public virtual short TabIndex {
332 return ViewState.GetShort ("TabIndex", 0);
335 ViewState ["TabIndex"] = value;
344 [WebSysDescription ("")]
345 [WebCategory ("Behavior")]
346 public virtual string ToolTip {
348 return ViewState.GetString ("ToolTip", string.Empty);
351 ViewState ["ToolTip"] = value;
358 [DefaultValue(typeof (Unit), "")]
359 [WebSysDescription ("")]
360 [WebCategory ("Layout")]
361 public virtual Unit Width {
369 ControlStyle.Width = value;
374 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
375 protected virtual HtmlTextWriterTag TagKey {
382 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
383 protected virtual string TagName {
385 // do this here to avoid potentially costly lookups on every control
386 if (tag_name == null)
387 tag_name = HtmlTextWriter.StaticGetTagName (TagKey);
394 internal bool IsEnabled
397 WebControl wc = this;
401 wc = wc.Parent as WebControl;
406 public static string DisabledCssClass {
412 public virtual bool SupportsDisabledAttribute {
415 public void ApplyStyle (Style s)
417 if (s != null && !s.IsEmpty)
418 ControlStyle.CopyFrom(s);
421 public void CopyBaseAttributes (WebControl controlSrc)
425 if (controlSrc == null)
428 Enabled = controlSrc.Enabled;
430 o = controlSrc.ViewState ["AccessKey"];
432 ViewState ["AccessKey"] = o;
434 o = controlSrc.ViewState ["TabIndex"];
436 ViewState ["TabIndex"] = o;
438 o = controlSrc.ViewState ["ToolTip"];
440 ViewState ["ToolTip"] = o;
442 if (controlSrc.attributes != null) {
443 AttributeCollection attributes = Attributes;
445 foreach (string s in controlSrc.attributes.Keys)
446 attributes [s] = controlSrc.attributes [s];
450 public void MergeStyle (Style s)
452 if (s != null && !s.IsEmpty)
453 ControlStyle.MergeWith(s);
456 public virtual void RenderBeginTag (HtmlTextWriter writer)
458 AddAttributesToRender (writer);
460 if (TagKey == HtmlTextWriterTag.Unknown)
461 writer.RenderBeginTag (TagName);
463 writer.RenderBeginTag (TagKey);
467 public virtual void RenderEndTag (HtmlTextWriter writer)
469 writer.RenderEndTag ();
472 static char[] _script_trim_chars = {';'};
473 internal string BuildScriptAttribute (string name, string tail)
475 AttributeCollection attrs = Attributes;
476 string attr = attrs [name];
478 if (attr == null || attr.Length == 0)
480 if (attr [attr.Length - 1] == ';')
481 attr = attr.TrimEnd (_script_trim_chars);
483 attr = String.Concat (attr, ";", tail);
489 internal void AddDisplayStyleAttribute (HtmlTextWriter writer)
491 if (!ControlStyleCreated)
494 if (!ControlStyle.BorderWidth.IsEmpty ||
495 (ControlStyle.BorderStyle != BorderStyle.None && ControlStyle.BorderStyle != BorderStyle.NotSet) ||
496 !ControlStyle.Height.IsEmpty ||
497 !ControlStyle.Width.IsEmpty)
498 writer.AddStyleAttribute (HtmlTextWriterStyle.Display, "inline-block");
500 void RenderDisabled (HtmlTextWriter writer)
503 if (!SupportsDisabledAttribute)
504 ControlStyle.PrependCssClass (DisabledCssClass);
506 writer.AddAttribute (HtmlTextWriterAttribute.Disabled, "disabled", false);
511 protected virtual void AddAttributesToRender (HtmlTextWriter writer)
513 RenderDisabled (writer);
515 writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
516 if (AccessKey != string.Empty)
517 writer.AddAttribute (HtmlTextWriterAttribute.Accesskey, AccessKey);
519 if (ToolTip != string.Empty)
520 writer.AddAttribute (HtmlTextWriterAttribute.Title, ToolTip);
523 writer.AddAttribute (HtmlTextWriterAttribute.Tabindex, TabIndex.ToString ());
525 if (style != null && !style.IsEmpty) {
526 //unbelievable, but see WebControlTest.RenderBeginTag_BorderWidth_xxx
527 if (TagKey == HtmlTextWriterTag.Span)
528 AddDisplayStyleAttribute (writer);
529 style.AddAttributesToRender(writer, this);
532 if (attributes != null)
533 foreach(string s in attributes.Keys)
534 writer.AddAttribute (s, attributes [s]);
537 protected virtual Style CreateControlStyle()
539 return new Style (ViewState);
542 protected override void LoadViewState (object savedState)
544 if (savedState == null || !(savedState is Pair)) {
545 base.LoadViewState (null);
549 Pair pair = (Pair) savedState;
551 base.LoadViewState (pair.First);
552 if (ViewState [System.Web.UI.WebControls.Style.BitStateKey] != null)
553 ControlStyle.LoadBitState ();
555 if (pair.Second != null) {
556 if (attribute_state == null) {
557 attribute_state = new StateBag ();
558 if (IsTrackingViewState)
559 attribute_state.TrackViewState ();
562 attribute_state.LoadViewState (pair.Second);
563 attributes = new AttributeCollection(attribute_state);
566 enabled = ViewState.GetBool ("Enabled", enabled);
568 internal virtual string InlinePropertiesSet ()
570 var properties = new List <string> ();
572 if (BackColor != Color.Empty)
573 properties.Add ("BackColor");
575 if (BorderColor != Color.Empty)
576 properties.Add ("BorderColor");
578 if (BorderStyle != BorderStyle.NotSet)
579 properties.Add ("BorderStyle");
581 if (BorderWidth != Unit.Empty)
582 properties.Add ("BorderWidth");
584 if (CssClass != String.Empty)
585 properties.Add ("CssClass");
587 if (ForeColor != Color.Empty)
588 properties.Add ("ForeColor");
590 if (Height != Unit.Empty)
591 properties.Add ("Height");
593 if (Width != Unit.Empty)
594 properties.Add ("Width");
596 if (properties.Count == 0)
599 return String.Join (", ", properties);
602 internal void VerifyInlinePropertiesNotSet ()
604 var renderOuterTableControl = this as IRenderOuterTable;
605 if (renderOuterTableControl == null || renderOuterTableControl.RenderOuterTable)
608 string properties = InlinePropertiesSet ();
609 if (!String.IsNullOrEmpty (properties)) {
610 bool many = properties.IndexOf (',') > -1;
611 throw new InvalidOperationException (
612 String.Format ("The style propert{0} '{1}' cannot be used while RenderOuterTable is disabled on the {2} control with ID '{3}'",
621 override void Render (HtmlTextWriter writer)
623 if (Adapter != null) {
624 Adapter.Render(writer);
627 RenderBeginTag (writer);
628 RenderContents (writer);
629 RenderEndTag (writer);
633 virtual void RenderContents (HtmlTextWriter writer)
635 base.Render (writer);
638 protected override object SaveViewState ()
640 if (track_enabled_state)
641 ViewState ["Enabled"] = enabled;
644 object attr_view_state = null;
647 style.SaveBitState ();
648 view_state = base.SaveViewState ();
650 if (attribute_state != null)
651 attr_view_state = attribute_state.SaveViewState ();
653 if (view_state == null && attr_view_state == null)
656 return new Pair (view_state, attr_view_state);
659 protected override void TrackViewState()
662 style.TrackViewState ();
664 if (attribute_state != null) {
665 attribute_state.TrackViewState ();
666 attribute_state.SetDirty (true);
669 base.TrackViewState ();
672 string IAttributeAccessor.GetAttribute (string key)
674 if (attributes != null)
675 return attributes [key];
680 void IAttributeAccessor.SetAttribute (string key, string value)
682 Attributes [key] = value;