WebControl.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  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:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  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.
  19. //
  20. // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
  21. //
  22. // Authors:
  23. // Peter Bartok ([email protected])
  24. //
  25. //
  26. using System.ComponentModel;
  27. using System.Drawing;
  28. using System.Security.Permissions;
  29. namespace System.Web.UI.WebControls {
  30. // CAS
  31. [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  32. [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  33. // attributes
  34. [ParseChildren (true)]
  35. #if NET_2_0
  36. [PersistChildrenAttribute (false, false)]
  37. [Themeable (true)]
  38. #else
  39. [PersistChildrenAttribute (false)]
  40. #endif
  41. public class WebControl : Control, IAttributeAccessor {
  42. Style style;
  43. HtmlTextWriterTag tag;
  44. string tag_name;
  45. AttributeCollection attributes;
  46. StateBag attribute_state;
  47. bool enabled;
  48. bool track_enabled_state;
  49. public WebControl (HtmlTextWriterTag tag)
  50. {
  51. this.tag = tag;
  52. this.enabled = true;
  53. }
  54. protected WebControl () : this (HtmlTextWriterTag.Span)
  55. {
  56. }
  57. protected WebControl (string tag)
  58. {
  59. this.tag = HtmlTextWriterTag.Unknown;
  60. this.tag_name = tag;
  61. this.enabled = true;
  62. }
  63. #if ONLY_1_1
  64. [Bindable(true)]
  65. #endif
  66. [DefaultValue("")]
  67. [WebSysDescription ("")]
  68. [WebCategory ("Behavior")]
  69. public virtual string AccessKey {
  70. get {
  71. return ViewState.GetString ("AccessKey", string.Empty);
  72. }
  73. set {
  74. if (value == null || value.Length < 2)
  75. ViewState ["AccessKey"] = value;
  76. else
  77. throw new ArgumentException ("AccessKey can only be null, empty or a single character", "value");
  78. }
  79. }
  80. [Browsable(false)]
  81. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  82. [WebSysDescription ("")]
  83. [WebCategory ("Behavior")]
  84. public AttributeCollection Attributes {
  85. get {
  86. if (attributes == null) {
  87. attribute_state = new StateBag (true);
  88. if (IsTrackingViewState)
  89. attribute_state.TrackViewState ();
  90. attributes = new AttributeCollection (attribute_state);
  91. }
  92. return attributes;
  93. }
  94. }
  95. #if ONLY_1_1
  96. [Bindable(true)]
  97. #endif
  98. [DefaultValue(typeof (Color), "")]
  99. [TypeConverter(typeof(System.Web.UI.WebControls.WebColorConverter))]
  100. [WebSysDescription ("")]
  101. [WebCategory ("Appearance")]
  102. public virtual Color BackColor {
  103. get {
  104. if (style == null)
  105. return Color.Empty;
  106. return style.BackColor;
  107. }
  108. set {
  109. ControlStyle.BackColor = value;
  110. }
  111. }
  112. #if ONLY_1_1
  113. [Bindable(true)]
  114. #endif
  115. [DefaultValue(typeof (Color), "")]
  116. [TypeConverter(typeof(System.Web.UI.WebControls.WebColorConverter))]
  117. [WebSysDescription ("")]
  118. [WebCategory ("Appearance")]
  119. public virtual Color BorderColor {
  120. get {
  121. if (style == null)
  122. return Color.Empty;
  123. return style.BorderColor;
  124. }
  125. set {
  126. ControlStyle.BorderColor = value;
  127. }
  128. }
  129. #if ONLY_1_1
  130. [Bindable(true)]
  131. #endif
  132. [DefaultValue(BorderStyle.NotSet)]
  133. [WebSysDescription ("")]
  134. [WebCategory ("Appearance")]
  135. public virtual BorderStyle BorderStyle {
  136. get {
  137. if (style == null)
  138. return BorderStyle.NotSet;
  139. return style.BorderStyle;
  140. }
  141. set {
  142. if (value < BorderStyle.NotSet || value > BorderStyle.Outset)
  143. throw new ArgumentOutOfRangeException ("value");
  144. ControlStyle.BorderStyle = value;
  145. }
  146. }
  147. #if ONLY_1_1
  148. [Bindable(true)]
  149. #endif
  150. [DefaultValue(typeof (Unit), "")]
  151. [WebSysDescription ("")]
  152. [WebCategory ("Appearance")]
  153. public virtual Unit BorderWidth {
  154. get {
  155. if (style == null)
  156. return Unit.Empty;
  157. return style.BorderWidth;
  158. }
  159. set {
  160. ControlStyle.BorderWidth = value;
  161. }
  162. }
  163. [Browsable(false)]
  164. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  165. [WebSysDescription ("")]
  166. [WebCategory ("Appearance")]
  167. public Style ControlStyle {
  168. get {
  169. if (style == null) {
  170. style = this.CreateControlStyle ();
  171. if (IsTrackingViewState)
  172. style.TrackViewState ();
  173. }
  174. return style;
  175. }
  176. }
  177. [Browsable(false)]
  178. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  179. #if NET_2_0
  180. [EditorBrowsable (EditorBrowsableState.Never)]
  181. #endif
  182. public bool ControlStyleCreated {
  183. get {
  184. return style != null;
  185. }
  186. }
  187. #if ONLY_1_1
  188. [Bindable(true)]
  189. #endif
  190. [DefaultValue("")]
  191. [WebSysDescription ("")]
  192. [WebCategory ("Appearance")]
  193. public virtual string CssClass {
  194. get {
  195. if (style == null)
  196. return string.Empty;
  197. return style.CssClass;
  198. }
  199. set {
  200. ControlStyle.CssClass = value;
  201. }
  202. }
  203. [Bindable(true)]
  204. [DefaultValue(true)]
  205. #if NET_2_0
  206. [Themeable (false)]
  207. #endif
  208. public virtual bool Enabled {
  209. get {
  210. return enabled;
  211. }
  212. set {
  213. if (enabled != value) {
  214. if (IsTrackingViewState)
  215. track_enabled_state = true;
  216. enabled = value;
  217. }
  218. }
  219. }
  220. #if NET_2_0
  221. [Browsable (true)]
  222. public virtual new bool EnableTheming
  223. {
  224. get { return base.EnableTheming; }
  225. set { base.EnableTheming = value; }
  226. }
  227. #endif
  228. #if ONLY_1_1
  229. [DefaultValue(null)]
  230. #endif
  231. [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
  232. [NotifyParentProperty(true)]
  233. [WebSysDescription ("")]
  234. [WebCategory ("Appearance")]
  235. public virtual FontInfo Font {
  236. get {
  237. // Oddly enough, it looks like we have to let it create the style
  238. // since we can't create a FontInfo without a style owner
  239. return ControlStyle.Font;
  240. }
  241. }
  242. #if ONLY_1_1
  243. [Bindable(true)]
  244. #endif
  245. [DefaultValue(typeof (Color), "")]
  246. [TypeConverter(typeof(System.Web.UI.WebControls.WebColorConverter))]
  247. [WebSysDescription ("")]
  248. [WebCategory ("Appearance")]
  249. public virtual Color ForeColor {
  250. get {
  251. if (style == null)
  252. return Color.Empty;
  253. return style.ForeColor;
  254. }
  255. set {
  256. ControlStyle.ForeColor = value;
  257. }
  258. }
  259. #if NET_2_0
  260. [Browsable (false)]
  261. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  262. public bool HasAttributes
  263. {
  264. get {
  265. return (attributes != null && attributes.Count > 0);
  266. }
  267. }
  268. #endif
  269. #if ONLY_1_1
  270. [Bindable(true)]
  271. #endif
  272. [DefaultValue(typeof (Unit), "")]
  273. [WebSysDescription ("")]
  274. [WebCategory ("Layout")]
  275. public virtual Unit Height {
  276. get {
  277. if (style == null)
  278. return Unit.Empty;
  279. return style.Height;
  280. }
  281. set {
  282. ControlStyle.Height = value;
  283. }
  284. }
  285. #if NET_2_0
  286. [Browsable (true)]
  287. public virtual new string SkinID
  288. {
  289. get { return base.SkinID; }
  290. set { base.SkinID = value; }
  291. }
  292. #endif
  293. [Browsable(false)]
  294. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  295. [WebSysDescription ("")]
  296. [WebCategory ("Style")]
  297. public CssStyleCollection Style {
  298. get {
  299. return Attributes.CssStyle;
  300. }
  301. }
  302. [DefaultValue((short)0)]
  303. [WebSysDescription ("")]
  304. [WebCategory ("Behavior")]
  305. public virtual short TabIndex {
  306. get {
  307. return ViewState.GetShort ("TabIndex", 0);
  308. }
  309. set {
  310. ViewState ["TabIndex"] = value;
  311. }
  312. }
  313. #if ONLY_1_1
  314. [Bindable(true)]
  315. #endif
  316. [DefaultValue("")]
  317. #if NET_2_0
  318. [Localizable (true)]
  319. #endif
  320. [WebSysDescription ("")]
  321. [WebCategory ("Behavior")]
  322. public virtual string ToolTip {
  323. get {
  324. return ViewState.GetString ("ToolTip", string.Empty);
  325. }
  326. set {
  327. ViewState ["ToolTip"] = value;
  328. }
  329. }
  330. #if ONLY_1_1
  331. [Bindable(true)]
  332. #endif
  333. [DefaultValue(typeof (Unit), "")]
  334. [WebSysDescription ("")]
  335. [WebCategory ("Layout")]
  336. public virtual Unit Width {
  337. get {
  338. if (style == null)
  339. return Unit.Empty;
  340. return style.Width;
  341. }
  342. set {
  343. ControlStyle.Width = value;
  344. }
  345. }
  346. [Browsable(false)]
  347. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  348. protected virtual HtmlTextWriterTag TagKey {
  349. get {
  350. return tag;
  351. }
  352. }
  353. [Browsable(false)]
  354. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  355. protected virtual string TagName {
  356. get {
  357. // do this here to avoid potentially costly lookups on every control
  358. if (tag_name == null)
  359. tag_name = HtmlTextWriter.StaticGetTagName (TagKey);
  360. return tag_name;
  361. }
  362. }
  363. #if NET_2_0
  364. protected internal bool IsEnabled
  365. {
  366. get {
  367. if (Enabled)
  368. return true;
  369. if(!HasControls())
  370. return false;
  371. for (int i = 0; i < Controls.Count; i++) {
  372. WebControl wc = Controls [i] as WebControl;
  373. if (wc != null && wc.IsEnabled)
  374. return true;
  375. }
  376. return false;
  377. }
  378. }
  379. #endif
  380. public void ApplyStyle (Style s)
  381. {
  382. if (s != null && !s.IsEmpty)
  383. ControlStyle.CopyFrom(s);
  384. }
  385. public void CopyBaseAttributes (WebControl controlSrc)
  386. {
  387. object o;
  388. if (controlSrc == null)
  389. return;
  390. Enabled = controlSrc.Enabled;
  391. o = controlSrc.ViewState ["AccessKey"];
  392. if (o != null)
  393. ViewState ["AccessKey"] = o;
  394. o = controlSrc.ViewState ["TabIndex"];
  395. if (o != null)
  396. ViewState ["TabIndex"] = o;
  397. o = controlSrc.ViewState ["ToolTip"];
  398. if (o != null)
  399. ViewState ["ToolTip"] = o;
  400. if (controlSrc.attributes != null)
  401. foreach (string s in controlSrc.attributes.Keys)
  402. Attributes [s] = controlSrc.attributes [s];
  403. }
  404. public void MergeStyle (Style s)
  405. {
  406. if (s != null && !s.IsEmpty)
  407. ControlStyle.MergeWith(s);
  408. }
  409. public virtual void RenderBeginTag (HtmlTextWriter writer)
  410. {
  411. AddAttributesToRender (writer);
  412. if (TagKey == HtmlTextWriterTag.Unknown)
  413. writer.RenderBeginTag (TagName);
  414. else
  415. writer.RenderBeginTag (TagKey);
  416. }
  417. public virtual void RenderEndTag (HtmlTextWriter writer)
  418. {
  419. writer.RenderEndTag ();
  420. }
  421. static char[] _script_trim_chars = {';'};
  422. internal string BuildScriptAttribute (string name, string tail)
  423. {
  424. AttributeCollection attrs = Attributes;
  425. string attr = attrs [name];
  426. if (attr == null || attr.Length == 0)
  427. return tail;
  428. if (attr [attr.Length - 1] == ';')
  429. attr = attr.TrimEnd (_script_trim_chars);
  430. attr = String.Concat (attr, ";", tail);
  431. attrs.Remove (name);
  432. return attr;
  433. }
  434. #if NET_2_0
  435. internal void AddDisplayStyleAttribute (HtmlTextWriter writer)
  436. {
  437. if (!ControlStyleCreated)
  438. return;
  439. if (!ControlStyle.BorderWidth.IsEmpty ||
  440. (ControlStyle.BorderStyle != BorderStyle.None && ControlStyle.BorderStyle != BorderStyle.NotSet) ||
  441. !ControlStyle.Height.IsEmpty ||
  442. !ControlStyle.Width.IsEmpty)
  443. writer.AddStyleAttribute (HtmlTextWriterStyle.Display, "inline-block");
  444. }
  445. #endif
  446. protected virtual void AddAttributesToRender (HtmlTextWriter writer)
  447. {
  448. if (ID != null)
  449. writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
  450. if (AccessKey != string.Empty)
  451. writer.AddAttribute (HtmlTextWriterAttribute.Accesskey, AccessKey);
  452. if (!enabled)
  453. writer.AddAttribute (HtmlTextWriterAttribute.Disabled, "disabled", false);
  454. if (ToolTip != string.Empty)
  455. writer.AddAttribute (HtmlTextWriterAttribute.Title, ToolTip);
  456. if (TabIndex != 0)
  457. writer.AddAttribute (HtmlTextWriterAttribute.Tabindex, TabIndex.ToString ());
  458. if (style != null && !style.IsEmpty) {
  459. #if NET_2_0
  460. //unbelievable, but see WebControlTest.RenderBeginTag_BorderWidth_xxx
  461. if (TagKey == HtmlTextWriterTag.Span)
  462. AddDisplayStyleAttribute (writer);
  463. #endif
  464. style.AddAttributesToRender(writer, this);
  465. }
  466. if (attributes != null)
  467. foreach(string s in attributes.Keys)
  468. writer.AddAttribute (s, attributes [s]);
  469. }
  470. protected virtual Style CreateControlStyle()
  471. {
  472. return new Style (ViewState);
  473. }
  474. protected override void LoadViewState (object savedState)
  475. {
  476. if (savedState == null) {
  477. base.LoadViewState (null);
  478. return;
  479. }
  480. Pair pair = (Pair) savedState;
  481. base.LoadViewState (pair.First);
  482. if (ViewState [System.Web.UI.WebControls.Style.BitStateKey] != null)
  483. ControlStyle.LoadBitState ();
  484. if (pair.Second != null) {
  485. if (attribute_state == null) {
  486. attribute_state = new StateBag ();
  487. if (IsTrackingViewState)
  488. attribute_state.TrackViewState ();
  489. }
  490. attribute_state.LoadViewState (pair.Second);
  491. attributes = new AttributeCollection(attribute_state);
  492. }
  493. enabled = ViewState.GetBool ("Enabled", enabled);
  494. }
  495. #if NET_2_0
  496. protected internal
  497. #else
  498. protected
  499. #endif
  500. override void Render (HtmlTextWriter writer)
  501. {
  502. RenderBeginTag (writer);
  503. RenderContents (writer);
  504. RenderEndTag (writer);
  505. }
  506. #if NET_2_0
  507. protected internal
  508. #else
  509. protected
  510. #endif
  511. virtual void RenderContents (HtmlTextWriter writer)
  512. {
  513. base.Render (writer);
  514. }
  515. protected override object SaveViewState ()
  516. {
  517. if (track_enabled_state)
  518. ViewState ["Enabled"] = enabled;
  519. object view_state;
  520. object attr_view_state = null;
  521. if (style != null)
  522. style.SaveBitState ();
  523. view_state = base.SaveViewState ();
  524. if (attribute_state != null)
  525. attr_view_state = attribute_state.SaveViewState ();
  526. if (view_state == null && attr_view_state == null)
  527. return null;
  528. return new Pair (view_state, attr_view_state);
  529. }
  530. protected override void TrackViewState()
  531. {
  532. if (style != null)
  533. style.TrackViewState ();
  534. if (attribute_state != null)
  535. attribute_state.TrackViewState ();
  536. base.TrackViewState ();
  537. }
  538. string IAttributeAccessor.GetAttribute (string key)
  539. {
  540. if (attributes != null)
  541. return attributes [key];
  542. return null;
  543. }
  544. void IAttributeAccessor.SetAttribute (string key, string value)
  545. {
  546. Attributes [key] = value;
  547. }
  548. }
  549. }