1 //------------------------------------------------------------------------------ 2 // <copyright file="SubMenuStyle.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 //------------------------------------------------------------------------------ 6 7 namespace System.Web.UI.WebControls { 8 using System.ComponentModel; 9 using System.Drawing; 10 using System.Globalization; 11 using System.Text; 12 using System.Web.UI; 13 14 /// <devdoc> 15 /// Specifies the style of a SubMenu. 16 /// </devdoc> 17 public class SubMenuStyle : Style, ICustomTypeDescriptor { 18 private const int PROP_VPADDING = 0x00010000; 19 private const int PROP_HPADDING = 0x00020000; 20 SubMenuStyle()21 public SubMenuStyle() : base() { 22 } 23 SubMenuStyle(StateBag bag)24 public SubMenuStyle(StateBag bag) : base(bag) { 25 } 26 27 /// <devdoc> 28 /// Gets and sets the horizontal padding around the node text 29 /// </devdoc> 30 [ 31 DefaultValue(typeof(Unit), ""), 32 WebCategory("Layout"), 33 NotifyParentProperty(true), 34 WebSysDescription(SR.SubMenuStyle_HorizontalPadding), 35 ] 36 public Unit HorizontalPadding { 37 get { 38 if (IsSet(PROP_HPADDING)) { 39 return (Unit)(ViewState["HorizontalPadding"]); 40 } 41 return Unit.Empty; 42 } 43 set { 44 if ((value.Type == UnitType.Percentage) || (value.Value < 0)) { 45 throw new ArgumentOutOfRangeException("value"); 46 } 47 ViewState["HorizontalPadding"] = value; 48 SetBit(PROP_HPADDING); 49 } 50 } 51 52 53 /// <devdoc> 54 /// Gets and sets the vertical padding around the node text 55 /// </devdoc> 56 [ 57 DefaultValue(typeof(Unit), ""), 58 WebCategory("Layout"), 59 NotifyParentProperty(true), 60 WebSysDescription(SR.SubMenuStyle_VerticalPadding), 61 ] 62 public Unit VerticalPadding { 63 get { 64 if (IsSet(PROP_VPADDING)) { 65 return (Unit)(ViewState["VerticalPadding"]); 66 } 67 return Unit.Empty; 68 } 69 set { 70 if ((value.Type == UnitType.Percentage) || (value.Value < 0)) { 71 throw new ArgumentOutOfRangeException("value"); 72 } 73 ViewState["VerticalPadding"] = value; 74 SetBit(PROP_VPADDING); 75 } 76 } 77 78 79 /// <devdoc> 80 /// Copies non-blank elements from the specified style, overwriting existing 81 /// style elements if necessary. 82 /// </devdoc> CopyFrom(Style s)83 public override void CopyFrom(Style s) { 84 if (s != null) { 85 base.CopyFrom(s); 86 87 SubMenuStyle sms = s as SubMenuStyle; 88 if (sms != null && !sms.IsEmpty) { 89 // Only copy the paddings if they aren't in the source Style's registered CSS class 90 if (s.RegisteredCssClass.Length != 0) { 91 if (sms.IsSet(PROP_VPADDING)) { 92 ViewState.Remove("VerticalPadding"); 93 ClearBit(PROP_VPADDING); 94 } 95 96 if (sms.IsSet(PROP_HPADDING)) { 97 ViewState.Remove("HorizontalPadding"); 98 ClearBit(PROP_HPADDING); 99 } 100 } 101 else { 102 if (sms.IsSet(PROP_VPADDING)) { 103 this.VerticalPadding = sms.VerticalPadding; 104 } 105 106 if (sms.IsSet(PROP_HPADDING)) { 107 this.HorizontalPadding = sms.HorizontalPadding; 108 } 109 } 110 } 111 } 112 } 113 114 FillStyleAttributes(CssStyleCollection attributes, IUrlResolutionService urlResolver)115 protected override void FillStyleAttributes(CssStyleCollection attributes, IUrlResolutionService urlResolver) { 116 // The style will be rendered on container elements that does not contain text directly. 117 // It does not render font and forecolor. 118 // Users should set font and forecolor on MenuItems styles. 119 // Copying the code from the base class, except for the part that deals with Font and ForeColor. 120 StateBag viewState = ViewState; 121 Color c; 122 123 // BackColor 124 if (base.IsSet(PROP_BACKCOLOR)) { 125 c = (Color)viewState["BackColor"]; 126 if (!c.IsEmpty) { 127 attributes.Add(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(c)); 128 } 129 } 130 131 // BorderColor 132 if (base.IsSet(PROP_BORDERCOLOR)) { 133 c = (Color)viewState["BorderColor"]; 134 if (!c.IsEmpty) { 135 attributes.Add(HtmlTextWriterStyle.BorderColor, ColorTranslator.ToHtml(c)); 136 } 137 } 138 139 BorderStyle bs = this.BorderStyle; 140 Unit bu = this.BorderWidth; 141 if (!bu.IsEmpty) { 142 attributes.Add(HtmlTextWriterStyle.BorderWidth, bu.ToString(CultureInfo.InvariantCulture)); 143 if (bs == BorderStyle.NotSet) { 144 if (bu.Value != 0.0) { 145 attributes.Add(HtmlTextWriterStyle.BorderStyle, "solid"); 146 } 147 } 148 else { 149 attributes.Add(HtmlTextWriterStyle.BorderStyle, borderStyles[(int)bs]); 150 } 151 } 152 else { 153 if (bs != BorderStyle.NotSet) { 154 attributes.Add(HtmlTextWriterStyle.BorderStyle, borderStyles[(int)bs]); 155 } 156 } 157 158 Unit u; 159 160 // Height 161 if (base.IsSet(PROP_HEIGHT)) { 162 u = (Unit)viewState["Height"]; 163 if (!u.IsEmpty) { 164 attributes.Add(HtmlTextWriterStyle.Height, u.ToString(CultureInfo.InvariantCulture)); 165 } 166 } 167 168 // Width 169 if (base.IsSet(PROP_WIDTH)) { 170 u = (Unit)viewState["Width"]; 171 if (!u.IsEmpty) { 172 attributes.Add(HtmlTextWriterStyle.Width, u.ToString(CultureInfo.InvariantCulture)); 173 } 174 } 175 176 if (!HorizontalPadding.IsEmpty || !VerticalPadding.IsEmpty) { 177 attributes.Add(HtmlTextWriterStyle.Padding, string.Format(CultureInfo.InvariantCulture, 178 "{0} {1} {0} {1}", 179 VerticalPadding.IsEmpty ? Unit.Pixel(0) : VerticalPadding, 180 HorizontalPadding.IsEmpty ? Unit.Pixel(0) : HorizontalPadding)); 181 } 182 } 183 184 185 /// <devdoc> 186 /// Copies non-blank elements from the specified style, but will not overwrite 187 /// any existing style elements. 188 /// </devdoc> MergeWith(Style s)189 public override void MergeWith(Style s) { 190 if (s != null) { 191 if (IsEmpty) { 192 // Merging with an empty style is equivalent to copying, 193 // which is more efficient. 194 CopyFrom(s); 195 return; 196 } 197 198 base.MergeWith(s); 199 200 SubMenuStyle sms = s as SubMenuStyle; 201 // Since we're already copying the registered CSS class in base.MergeWith, we don't 202 // need to any attributes that would be included in that class. 203 if (sms != null && !sms.IsEmpty && s.RegisteredCssClass.Length == 0) { 204 if (sms.IsSet(PROP_VPADDING) && !this.IsSet(PROP_VPADDING)) { 205 this.VerticalPadding = sms.VerticalPadding; 206 } 207 208 if (sms.IsSet(PROP_HPADDING) && !this.IsSet(PROP_HPADDING)) { 209 this.HorizontalPadding = sms.HorizontalPadding; 210 } 211 } 212 } 213 } 214 215 216 /// <devdoc> 217 /// Clears out any defined style elements from the state bag. 218 /// </devdoc> Reset()219 public override void Reset() { 220 if (IsSet(PROP_VPADDING)) 221 ViewState.Remove("VerticalPadding"); 222 if (IsSet(PROP_HPADDING)) 223 ViewState.Remove("HorizontalPadding"); 224 225 base.Reset(); 226 } 227 228 229 #region ICustomTypeDesciptor implementation ICustomTypeDescriptor.GetAttributes()230 System.ComponentModel.AttributeCollection ICustomTypeDescriptor.GetAttributes() { 231 return TypeDescriptor.GetAttributes(this, true); 232 } 233 ICustomTypeDescriptor.GetClassName()234 string ICustomTypeDescriptor.GetClassName() { 235 return TypeDescriptor.GetClassName(this, true); 236 } 237 ICustomTypeDescriptor.GetComponentName()238 string ICustomTypeDescriptor.GetComponentName() { 239 return TypeDescriptor.GetComponentName(this, true); 240 } 241 ICustomTypeDescriptor.GetConverter()242 TypeConverter ICustomTypeDescriptor.GetConverter() { 243 return TypeDescriptor.GetConverter(this, true); 244 } 245 ICustomTypeDescriptor.GetDefaultEvent()246 EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { 247 return TypeDescriptor.GetDefaultEvent(this, true); 248 } 249 ICustomTypeDescriptor.GetDefaultProperty()250 PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() { 251 return TypeDescriptor.GetDefaultProperty(this, true); 252 } 253 ICustomTypeDescriptor.GetEditor(Type editorBaseType)254 object ICustomTypeDescriptor.GetEditor(Type editorBaseType) { 255 return TypeDescriptor.GetEditor(this, editorBaseType, true); 256 } 257 ICustomTypeDescriptor.GetEvents()258 EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { 259 return TypeDescriptor.GetEvents(this, true); 260 } 261 ICustomTypeDescriptor.GetEvents(Attribute[] attributes)262 EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) { 263 return TypeDescriptor.GetEvents(this, attributes, true); 264 } 265 ICustomTypeDescriptor.GetProperties()266 PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() { 267 return ((ICustomTypeDescriptor)this).GetProperties(null); 268 } 269 ICustomTypeDescriptor.GetProperties(Attribute[] attributes)270 PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { 271 PropertyDescriptorCollection oldProperties = TypeDescriptor.GetProperties(GetType(), attributes); 272 PropertyDescriptor[] newProperties = new PropertyDescriptor[oldProperties.Count]; 273 274 PropertyDescriptor fontProperty = oldProperties["Font"]; 275 PropertyDescriptor forecolorProperty = oldProperties["ForeColor"]; 276 277 Attribute[] newAttributes = new Attribute[] { 278 new BrowsableAttribute(false), 279 new EditorBrowsableAttribute(EditorBrowsableState.Never), 280 new ThemeableAttribute(false), 281 }; 282 283 for (int i = 0; i < oldProperties.Count; i++) { 284 PropertyDescriptor property = oldProperties[i]; 285 if ((property == fontProperty) || (property == forecolorProperty)) { 286 newProperties[i] = TypeDescriptor.CreateProperty(GetType(), property, newAttributes); 287 } 288 else { 289 newProperties[i] = property; 290 } 291 } 292 293 return new PropertyDescriptorCollection(newProperties, true); 294 } 295 ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)296 object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) { 297 return this; 298 } 299 #endregion //ICustomTypeDescriptor implementation 300 301 } 302 } 303