SiteMapPath.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. //
  2. // System.Web.UI.WebControls.SiteMapPath.cs
  3. //
  4. // Authors:
  5. // Lluis Sanchez Gual ([email protected])
  6. //
  7. // (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. // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
  29. //
  30. #if NET_2_0
  31. using System;
  32. using System.Collections;
  33. using System.ComponentModel;
  34. using System.Web.UI.HtmlControls;
  35. namespace System.Web.UI.WebControls
  36. {
  37. [Designer ("System.Web.UI.Design.WebControls.SiteMapPathDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
  38. public class SiteMapPath: CompositeControl
  39. {
  40. SiteMapProvider provider;
  41. Style currentNodeStyle;
  42. Style nodeStyle;
  43. Style pathSeparatorStyle;
  44. Style rootNodeStyle;
  45. ITemplate currentNodeTemplate;
  46. ITemplate nodeTemplate;
  47. ITemplate pathSeparatorTemplate;
  48. ITemplate rootNodeTemplate;
  49. static readonly object ItemCreatedEvent = new object();
  50. static readonly object ItemDataBoundEvent = new object();
  51. public event SiteMapNodeItemEventHandler ItemCreated {
  52. add { Events.AddHandler (ItemCreatedEvent, value); }
  53. remove { Events.RemoveHandler (ItemCreatedEvent, value); }
  54. }
  55. public event SiteMapNodeItemEventHandler ItemDataBound {
  56. add { Events.AddHandler (ItemDataBoundEvent, value); }
  57. remove { Events.RemoveHandler (ItemDataBoundEvent, value); }
  58. }
  59. protected virtual void OnItemCreated (SiteMapNodeItemEventArgs e)
  60. {
  61. if (Events != null) {
  62. SiteMapNodeItemEventHandler eh = (SiteMapNodeItemEventHandler) Events [ItemCreatedEvent];
  63. if (eh != null) eh (this, e);
  64. }
  65. }
  66. protected virtual void OnItemDataBound (SiteMapNodeItemEventArgs e)
  67. {
  68. if (Events != null) {
  69. SiteMapNodeItemEventHandler eh = (SiteMapNodeItemEventHandler) Events [ItemDataBoundEvent];
  70. if (eh != null) eh (this, e);
  71. }
  72. }
  73. [DefaultValueAttribute (null)]
  74. [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
  75. [NotifyParentPropertyAttribute (true)]
  76. [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
  77. public Style CurrentNodeStyle {
  78. get {
  79. if (currentNodeStyle == null) {
  80. currentNodeStyle = new Style ();
  81. if (IsTrackingViewState)
  82. ((IStateManager)currentNodeStyle).TrackViewState ();
  83. }
  84. return currentNodeStyle;
  85. }
  86. }
  87. [DefaultValue (null)]
  88. [TemplateContainer (typeof(SiteMapNodeItem), BindingDirection.OneWay)]
  89. [PersistenceMode (PersistenceMode.InnerProperty)]
  90. [Browsable (false)]
  91. public virtual ITemplate CurrentNodeTemplate {
  92. get { return currentNodeTemplate; }
  93. set { currentNodeTemplate = value; UpdateControls (); }
  94. }
  95. [DefaultValueAttribute (null)]
  96. [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
  97. [NotifyParentPropertyAttribute (true)]
  98. [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
  99. public Style NodeStyle {
  100. get {
  101. if (nodeStyle == null) {
  102. nodeStyle = new Style ();
  103. if (IsTrackingViewState)
  104. ((IStateManager)nodeStyle).TrackViewState ();
  105. }
  106. return nodeStyle;
  107. }
  108. }
  109. [DefaultValue (null)]
  110. [TemplateContainer (typeof(SiteMapNodeItem), BindingDirection.OneWay)]
  111. [PersistenceMode (PersistenceMode.InnerProperty)]
  112. [Browsable (false)]
  113. public virtual ITemplate NodeTemplate {
  114. get { return nodeTemplate; }
  115. set { nodeTemplate = value; UpdateControls (); }
  116. }
  117. [DefaultValueAttribute (-1)]
  118. [ThemeableAttribute (false)]
  119. public virtual int ParentLevelsDisplayed {
  120. get { return ViewState.GetInt ("ParentLevelsDisplayed", -1); }
  121. set {
  122. if (value < -1) throw new ArgumentOutOfRangeException ("value");
  123. ViewState ["ParentLevelsDisplayed"] = value;
  124. UpdateControls ();
  125. }
  126. }
  127. [DefaultValueAttribute (PathDirection.RootToCurrent)]
  128. public virtual PathDirection PathDirection {
  129. get { return (PathDirection)ViewState.GetInt ("PathDirection", (int)PathDirection.RootToCurrent); }
  130. set {
  131. if (value != PathDirection.RootToCurrent && value != PathDirection.CurrentToRoot)
  132. throw new ArgumentOutOfRangeException ("value");
  133. ViewState ["PathDirection"] = value;
  134. UpdateControls ();
  135. }
  136. }
  137. [DefaultValueAttribute (" > ")]
  138. [LocalizableAttribute (true)]
  139. public virtual string PathSeparator {
  140. get { return ViewState.GetString ("PathSeparator", " > "); }
  141. set {
  142. ViewState ["PathSeparator"] = value;
  143. UpdateControls ();
  144. }
  145. }
  146. [DefaultValueAttribute (null)]
  147. [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
  148. [NotifyParentPropertyAttribute (true)]
  149. [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
  150. public Style PathSeparatorStyle {
  151. get {
  152. if (pathSeparatorStyle == null) {
  153. pathSeparatorStyle = new Style ();
  154. if (IsTrackingViewState)
  155. ((IStateManager)pathSeparatorStyle).TrackViewState ();
  156. }
  157. return pathSeparatorStyle;
  158. }
  159. }
  160. [DefaultValue (null)]
  161. [TemplateContainer (typeof(SiteMapNodeItem), BindingDirection.OneWay)]
  162. [PersistenceMode (PersistenceMode.InnerProperty)]
  163. [Browsable (false)]
  164. public virtual ITemplate PathSeparatorTemplate {
  165. get { return pathSeparatorTemplate; }
  166. set { pathSeparatorTemplate = value; UpdateControls (); }
  167. }
  168. [BrowsableAttribute (false)]
  169. [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
  170. public SiteMapProvider Provider {
  171. get {
  172. if (provider == null) {
  173. if (this.SiteMapProvider.Length == 0) {
  174. provider = SiteMap.Provider;
  175. if (provider == null)
  176. throw new HttpException ("There is no default provider configured for the site.");
  177. } else {
  178. provider = SiteMap.Providers [this.SiteMapProvider];
  179. if (provider == null)
  180. throw new HttpException ("SiteMap provider '" + this.SiteMapProvider + "' not found.");
  181. }
  182. }
  183. return provider;
  184. }
  185. set {
  186. provider = value;
  187. UpdateControls ();
  188. }
  189. }
  190. [DefaultValueAttribute (false)]
  191. public virtual bool RenderCurrentNodeAsLink {
  192. get { return ViewState.GetBool ("RenderCurrentNodeAsLink", false); }
  193. set {
  194. ViewState ["RenderCurrentNodeAsLink"] = value;
  195. UpdateControls ();
  196. }
  197. }
  198. [DefaultValueAttribute (null)]
  199. [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
  200. [NotifyParentPropertyAttribute (true)]
  201. [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
  202. public Style RootNodeStyle {
  203. get {
  204. if (rootNodeStyle == null) {
  205. rootNodeStyle = new Style ();
  206. if (IsTrackingViewState)
  207. ((IStateManager)rootNodeStyle).TrackViewState ();
  208. }
  209. return rootNodeStyle;
  210. }
  211. }
  212. [DefaultValue (null)]
  213. [TemplateContainer (typeof(SiteMapNodeItem), BindingDirection.OneWay)]
  214. [PersistenceMode (PersistenceMode.InnerProperty)]
  215. [Browsable (false)]
  216. public virtual ITemplate RootNodeTemplate {
  217. get { return rootNodeTemplate; }
  218. set { rootNodeTemplate = value; UpdateControls (); }
  219. }
  220. [DefaultValueAttribute (true)]
  221. [ThemeableAttribute (false)]
  222. public virtual bool ShowToolTips {
  223. get { return ViewState.GetBool ("ShowToolTips", true); }
  224. set {
  225. ViewState ["ShowToolTips"] = value;
  226. UpdateControls ();
  227. }
  228. }
  229. [DefaultValueAttribute ("")]
  230. [ThemeableAttribute (false)]
  231. public virtual string SiteMapProvider {
  232. get { return ViewState.GetString ("SiteMapProvider", ""); }
  233. set {
  234. ViewState ["SiteMapProvider"] = value;
  235. UpdateControls ();
  236. }
  237. }
  238. [Localizable (true)]
  239. public virtual string SkipLinkText
  240. {
  241. get { return ViewState.GetString ("SkipLinkText", "Skip Navigation Links"); }
  242. set { ViewState["SkipLinkText"] = value; }
  243. }
  244. void UpdateControls ()
  245. {
  246. ChildControlsCreated = false;
  247. }
  248. public override void DataBind ()
  249. {
  250. base.DataBind ();
  251. /* the child controls get bound in
  252. * base.DataBind */
  253. foreach (Control c in Controls) {
  254. if (c is SiteMapNodeItem) {
  255. SiteMapNodeItem it = (SiteMapNodeItem)c;
  256. OnItemDataBound (new SiteMapNodeItemEventArgs (it));
  257. }
  258. }
  259. }
  260. protected internal override void CreateChildControls ()
  261. {
  262. Controls.Clear ();
  263. CreateControlHierarchy ();
  264. DataBind ();
  265. }
  266. protected virtual void CreateControlHierarchy ()
  267. {
  268. ArrayList nodes = new ArrayList ();
  269. SiteMapNode node = Provider.CurrentNode;
  270. if (node == null) return;
  271. int levels = ParentLevelsDisplayed != -1 ? ParentLevelsDisplayed + 1 : int.MaxValue;
  272. while (node != null && levels > 0) {
  273. if (nodes.Count > 0) {
  274. SiteMapNodeItem sep = new SiteMapNodeItem (nodes.Count, SiteMapNodeItemType.PathSeparator);
  275. InitializeItem (sep);
  276. SiteMapNodeItemEventArgs sargs = new SiteMapNodeItemEventArgs (sep);
  277. OnItemCreated (sargs);
  278. nodes.Add (sep);
  279. }
  280. SiteMapNodeItemType nt;
  281. if (nodes.Count == 0)
  282. nt = SiteMapNodeItemType.Current;
  283. else if (node.ParentNode == null)
  284. nt = SiteMapNodeItemType.Root;
  285. else
  286. nt = SiteMapNodeItemType.Parent;
  287. SiteMapNodeItem it = new SiteMapNodeItem (nodes.Count, nt);
  288. it.SiteMapNode = node;
  289. InitializeItem (it);
  290. SiteMapNodeItemEventArgs args = new SiteMapNodeItemEventArgs (it);
  291. OnItemCreated (args);
  292. nodes.Add (it);
  293. node = node.ParentNode;
  294. levels--;
  295. }
  296. if (PathDirection == PathDirection.RootToCurrent) {
  297. for (int n=nodes.Count - 1; n>=0; n--)
  298. Controls.Add ((Control)nodes[n]);
  299. } else {
  300. for (int n=0; n<nodes.Count; n++)
  301. Controls.Add ((Control)nodes[n]);
  302. }
  303. }
  304. protected virtual void InitializeItem (SiteMapNodeItem item)
  305. {
  306. switch (item.ItemType) {
  307. case SiteMapNodeItemType.Root:
  308. if (RootNodeTemplate != null) {
  309. item.ApplyStyle (NodeStyle);
  310. item.ApplyStyle (RootNodeStyle);
  311. RootNodeTemplate.InstantiateIn (item);
  312. }
  313. else if (NodeTemplate != null) {
  314. item.ApplyStyle (NodeStyle);
  315. item.ApplyStyle (RootNodeStyle);
  316. NodeTemplate.InstantiateIn (item);
  317. }
  318. else {
  319. WebControl c = CreateHyperLink (item);
  320. c.ApplyStyle (NodeStyle);
  321. c.ApplyStyle (RootNodeStyle);
  322. item.Controls.Add (c);
  323. }
  324. break;
  325. case SiteMapNodeItemType.Current:
  326. if (CurrentNodeTemplate != null) {
  327. item.ApplyStyle (NodeStyle);
  328. item.ApplyStyle (CurrentNodeStyle);
  329. CurrentNodeTemplate.InstantiateIn (item);
  330. }
  331. else if (NodeTemplate != null) {
  332. item.ApplyStyle (NodeStyle);
  333. item.ApplyStyle (CurrentNodeStyle);
  334. NodeTemplate.InstantiateIn (item);
  335. } else if (RenderCurrentNodeAsLink) {
  336. HyperLink c = CreateHyperLink (item);
  337. c.ApplyStyle (NodeStyle);
  338. c.ApplyStyle (CurrentNodeStyle);
  339. item.Controls.Add (c);
  340. } else {
  341. Literal c = CreateLiteral (item);
  342. item.ApplyStyle (NodeStyle);
  343. item.ApplyStyle (CurrentNodeStyle);
  344. item.Controls.Add (c);
  345. }
  346. break;
  347. case SiteMapNodeItemType.Parent:
  348. if (NodeTemplate != null) {
  349. item.ApplyStyle (NodeStyle);
  350. NodeTemplate.InstantiateIn (item);
  351. }
  352. else {
  353. WebControl c = CreateHyperLink (item);
  354. c.ApplyStyle (NodeStyle);
  355. item.Controls.Add (c);
  356. }
  357. break;
  358. case SiteMapNodeItemType.PathSeparator:
  359. if (PathSeparatorTemplate != null) {
  360. item.ApplyStyle (PathSeparatorStyle);
  361. PathSeparatorTemplate.InstantiateIn (item);
  362. } else {
  363. Literal h = new Literal ();
  364. h.Text = HttpUtility.HtmlEncode (PathSeparator);
  365. item.ApplyStyle (PathSeparatorStyle);
  366. item.Controls.Add (h);
  367. }
  368. break;
  369. }
  370. }
  371. HyperLink CreateHyperLink (SiteMapNodeItem item)
  372. {
  373. HyperLink h = new HyperLink ();
  374. h.Text = item.SiteMapNode.Title;
  375. h.NavigateUrl = item.SiteMapNode.Url;
  376. if (ShowToolTips)
  377. h.ToolTip = item.SiteMapNode.Description;
  378. return h;
  379. }
  380. Literal CreateLiteral (SiteMapNodeItem item)
  381. {
  382. Literal h = new Literal ();
  383. h.Text = item.SiteMapNode.Title;
  384. return h;
  385. }
  386. protected override void LoadViewState (object savedState)
  387. {
  388. if (savedState == null) {
  389. base.LoadViewState (null);
  390. return;
  391. }
  392. object[] states = (object[]) savedState;
  393. base.LoadViewState (states [0]);
  394. if (states[1] != null) ((IStateManager)CurrentNodeStyle).LoadViewState (states[1]);
  395. if (states[2] != null) ((IStateManager)NodeStyle).LoadViewState (states[2]);
  396. if (states[3] != null) ((IStateManager)PathSeparatorStyle).LoadViewState (states[3]);
  397. if (states[4] != null) ((IStateManager)RootNodeStyle).LoadViewState (states[4]);
  398. }
  399. [MonoTODO ("why override?")]
  400. protected override void OnDataBinding (EventArgs e)
  401. {
  402. base.OnDataBinding (e);
  403. }
  404. [MonoTODO ("why override?")]
  405. protected internal override void Render (HtmlTextWriter w)
  406. {
  407. base.Render (w);
  408. }
  409. protected internal override void RenderContents (HtmlTextWriter w)
  410. {
  411. string skip_id = ClientID + "_SkipLink";
  412. string altText = SkipLinkText;
  413. bool needAnchor = !String.IsNullOrEmpty (altText);
  414. if (needAnchor) {
  415. // Anchor start
  416. w.AddAttribute (HtmlTextWriterAttribute.Href, "#" + skip_id);
  417. w.RenderBeginTag (HtmlTextWriterTag.A);
  418. // Image
  419. w.AddAttribute (HtmlTextWriterAttribute.Alt, altText);
  420. w.AddAttribute (HtmlTextWriterAttribute.Height, "0");
  421. w.AddAttribute (HtmlTextWriterAttribute.Width, "0");
  422. w.AddAttribute (HtmlTextWriterAttribute.Src, Page.ClientScript.GetWebResourceUrl (typeof (SiteMapPath), "transparent.gif"));
  423. w.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0px");
  424. w.RenderBeginTag (HtmlTextWriterTag.Img);
  425. w.RenderEndTag ();
  426. w.RenderEndTag ();
  427. }
  428. base.RenderContents (w);
  429. if (needAnchor) {
  430. w.AddAttribute(HtmlTextWriterAttribute.Id, skip_id);
  431. w.RenderBeginTag(HtmlTextWriterTag.A);
  432. w.RenderEndTag();
  433. }
  434. }
  435. protected override object SaveViewState ()
  436. {
  437. object[] state = new object [5];
  438. state [0] = base.SaveViewState ();
  439. if (currentNodeStyle != null) state [1] = ((IStateManager)currentNodeStyle).SaveViewState ();
  440. if (nodeStyle != null) state [2] = ((IStateManager)nodeStyle).SaveViewState ();
  441. if (pathSeparatorStyle != null) state [3] = ((IStateManager)pathSeparatorStyle).SaveViewState ();
  442. if (rootNodeStyle != null) state [4] = ((IStateManager)rootNodeStyle).SaveViewState ();
  443. for (int n=0; n<state.Length; n++)
  444. if (state [n] != null) return state;
  445. return null;
  446. }
  447. protected override void TrackViewState ()
  448. {
  449. base.TrackViewState();
  450. if (currentNodeStyle != null) ((IStateManager)currentNodeStyle).TrackViewState();
  451. if (nodeStyle != null) ((IStateManager)nodeStyle).TrackViewState();
  452. if (pathSeparatorStyle != null) ((IStateManager)pathSeparatorStyle).TrackViewState();
  453. if (rootNodeStyle != null) ((IStateManager)rootNodeStyle).TrackViewState();
  454. }
  455. }
  456. }
  457. #endif