TreeView.cs 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046
  1. //
  2. // System.Web.UI.WebControls.TreeView.cs
  3. //
  4. // Authors:
  5. // Lluis Sanchez Gual ([email protected])
  6. //
  7. // (C) 2004 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) 2004 Novell, Inc (http://www.novell.com)
  29. //
  30. #if NET_2_0
  31. using System.Collections;
  32. using System.Text;
  33. using System.ComponentModel;
  34. using System.Globalization;
  35. using System.Web.Handlers;
  36. using System.Collections.Specialized;
  37. using System.IO;
  38. using System.Security.Permissions;
  39. using System.Collections.Generic;
  40. using System.Web.Util;
  41. namespace System.Web.UI.WebControls
  42. {
  43. // CAS
  44. [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  45. [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  46. // attributes
  47. [SupportsEventValidation]
  48. [ControlValueProperty ("SelectedValue")]
  49. [DefaultEvent ("SelectedNodeChanged")]
  50. [Designer ("System.Web.UI.Design.WebControls.TreeViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
  51. public class TreeView: HierarchicalDataBoundControl, IPostBackEventHandler, IPostBackDataHandler, ICallbackEventHandler
  52. {
  53. static readonly char[] postDataSplitChars = {'|'};
  54. string activeSiteMapPath;
  55. bool stylesPrepared;
  56. Style hoverNodeStyle;
  57. TreeNodeStyle leafNodeStyle;
  58. TreeNodeStyle nodeStyle;
  59. TreeNodeStyle parentNodeStyle;
  60. TreeNodeStyle rootNodeStyle;
  61. TreeNodeStyle selectedNodeStyle;
  62. TreeNodeStyleCollection levelStyles;
  63. TreeNodeCollection nodes;
  64. TreeNodeBindingCollection dataBindings;
  65. TreeNode selectedNode;
  66. Hashtable bindings;
  67. int registeredStylesCounter = -1;
  68. List<Style> levelLinkStyles;
  69. Style controlLinkStyle;
  70. Style nodeLinkStyle;
  71. Style rootNodeLinkStyle;
  72. Style parentNodeLinkStyle;
  73. Style leafNodeLinkStyle;
  74. Style selectedNodeLinkStyle;
  75. Style hoverNodeLinkStyle;
  76. static readonly object TreeNodeCheckChangedEvent = new object();
  77. static readonly object SelectedNodeChangedEvent = new object();
  78. static readonly object TreeNodeCollapsedEvent = new object();
  79. static readonly object TreeNodeDataBoundEvent = new object();
  80. static readonly object TreeNodeExpandedEvent = new object();
  81. static readonly object TreeNodePopulateEvent = new object();
  82. static Hashtable imageStyles = new Hashtable ();
  83. class TreeViewExpandDepthConverter : TypeConverter
  84. {
  85. public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
  86. {
  87. if (sourceType == typeof (string) || sourceType == typeof (int))
  88. return true;
  89. return base.CanConvertFrom (context, sourceType);
  90. }
  91. public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType)
  92. {
  93. if (destinationType == typeof (string) || destinationType == typeof (int))
  94. return true;
  95. return base.CanConvertTo (context, destinationType);
  96. }
  97. public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
  98. {
  99. if (destinationType != typeof (int) && destinationType != typeof (string))
  100. return base.ConvertTo (context, culture, value, destinationType);
  101. if (value is string) {
  102. if (destinationType == typeof (int)) {
  103. if (String.Compare ("FullyExpand", (string)value, StringComparison.OrdinalIgnoreCase) == 0)
  104. return -1;
  105. try {
  106. return Int32.Parse ((string)value);
  107. } catch (Exception) {
  108. return -1;
  109. }
  110. } else
  111. return value;
  112. }
  113. int val = (int)value;
  114. if (destinationType == typeof (string)) {
  115. if (val == -1)
  116. return "FullyExpand";
  117. return val.ToString ();
  118. }
  119. return value;
  120. }
  121. public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value)
  122. {
  123. if (!(value is string) && !(value is int))
  124. return base.ConvertFrom (context, culture, value);
  125. if (value is string) {
  126. if (String.Compare ("FullyExpand", (string)value, StringComparison.OrdinalIgnoreCase) == 0)
  127. return -1;
  128. try {
  129. return Int32.Parse ((string)value);
  130. } catch (Exception) {
  131. return null;
  132. }
  133. }
  134. return value;
  135. }
  136. }
  137. class ImageStyle
  138. {
  139. public ImageStyle (string expand, string collapse, string noExpand, string icon, string iconLeaf, string iconRoot)
  140. {
  141. Expand = expand;
  142. Collapse = collapse;
  143. NoExpand = noExpand;
  144. RootIcon = iconRoot;
  145. ParentIcon = icon;
  146. LeafIcon = iconLeaf;
  147. }
  148. public string Expand;
  149. public string Collapse;
  150. public string NoExpand;
  151. public string RootIcon;
  152. public string ParentIcon;
  153. public string LeafIcon;
  154. }
  155. static TreeView ()
  156. {
  157. imageStyles [TreeViewImageSet.Arrows] = new ImageStyle ("arrow_plus", "arrow_minus", "arrow_noexpand", null, null, null);
  158. imageStyles [TreeViewImageSet.BulletedList] = new ImageStyle (null, null, null, "dot_full", "dot_empty", "dot_full");
  159. imageStyles [TreeViewImageSet.BulletedList2] = new ImageStyle (null, null, null, "box_full", "box_empty", "box_full");
  160. imageStyles [TreeViewImageSet.BulletedList3] = new ImageStyle (null, null, null, "star_full", "star_empty", "star_full");
  161. imageStyles [TreeViewImageSet.BulletedList4] = new ImageStyle (null, null, null, "star_full", "star_empty", "dots");
  162. imageStyles [TreeViewImageSet.Contacts] = new ImageStyle ("TreeView_plus", "TreeView_minus", "contact", null, null, null);
  163. imageStyles [TreeViewImageSet.Events] = new ImageStyle (null, null, null, "warning", "warning", "warning");
  164. imageStyles [TreeViewImageSet.Inbox] = new ImageStyle (null, null, null, "inbox", "inbox", "inbox");
  165. imageStyles [TreeViewImageSet.Msdn] = new ImageStyle ("box_plus", "box_minus", "box_noexpand", null, null, null);
  166. imageStyles [TreeViewImageSet.Simple] = new ImageStyle (null, null, "box_full", null, null, null);
  167. imageStyles [TreeViewImageSet.Simple2] = new ImageStyle (null, null, "box_empty", null, null, null);
  168. // TODO
  169. imageStyles [TreeViewImageSet.News] = new ImageStyle ("TreeView_plus", "TreeView_minus", "TreeView_noexpand", null, null, null);
  170. imageStyles [TreeViewImageSet.Faq] = new ImageStyle ("TreeView_plus", "TreeView_minus", "TreeView_noexpand", null, null, null);
  171. imageStyles [TreeViewImageSet.WindowsHelp] = new ImageStyle ("TreeView_plus", "TreeView_minus", "TreeView_noexpand", null, null, null);
  172. imageStyles [TreeViewImageSet.XPFileExplorer] = new ImageStyle ("TreeView_plus", "TreeView_minus", "TreeView_noexpand", "folder", "file", "computer");
  173. }
  174. public event TreeNodeEventHandler TreeNodeCheckChanged {
  175. add { Events.AddHandler (TreeNodeCheckChangedEvent, value); }
  176. remove { Events.RemoveHandler (TreeNodeCheckChangedEvent, value); }
  177. }
  178. public event EventHandler SelectedNodeChanged {
  179. add { Events.AddHandler (SelectedNodeChangedEvent, value); }
  180. remove { Events.RemoveHandler (SelectedNodeChangedEvent, value); }
  181. }
  182. public event TreeNodeEventHandler TreeNodeCollapsed {
  183. add { Events.AddHandler (TreeNodeCollapsedEvent, value); }
  184. remove { Events.RemoveHandler (TreeNodeCollapsedEvent, value); }
  185. }
  186. public event TreeNodeEventHandler TreeNodeDataBound {
  187. add { Events.AddHandler (TreeNodeDataBoundEvent, value); }
  188. remove { Events.RemoveHandler (TreeNodeDataBoundEvent, value); }
  189. }
  190. public event TreeNodeEventHandler TreeNodeExpanded {
  191. add { Events.AddHandler (TreeNodeExpandedEvent, value); }
  192. remove { Events.RemoveHandler (TreeNodeExpandedEvent, value); }
  193. }
  194. public event TreeNodeEventHandler TreeNodePopulate {
  195. add { Events.AddHandler (TreeNodePopulateEvent, value); }
  196. remove { Events.RemoveHandler (TreeNodePopulateEvent, value); }
  197. }
  198. protected virtual void OnTreeNodeCheckChanged (TreeNodeEventArgs e)
  199. {
  200. if (Events != null) {
  201. TreeNodeEventHandler eh = (TreeNodeEventHandler) Events [TreeNodeCheckChangedEvent];
  202. if (eh != null)
  203. eh (this, e);
  204. }
  205. }
  206. protected virtual void OnSelectedNodeChanged (EventArgs e)
  207. {
  208. if (Events != null) {
  209. EventHandler eh = (EventHandler) Events [SelectedNodeChangedEvent];
  210. if (eh != null)
  211. eh (this, e);
  212. }
  213. }
  214. protected virtual void OnTreeNodeCollapsed (TreeNodeEventArgs e)
  215. {
  216. if (Events != null) {
  217. TreeNodeEventHandler eh = (TreeNodeEventHandler) Events [TreeNodeCollapsedEvent];
  218. if (eh != null)
  219. eh (this, e);
  220. }
  221. }
  222. protected virtual void OnTreeNodeDataBound (TreeNodeEventArgs e)
  223. {
  224. if (Events != null) {
  225. TreeNodeEventHandler eh = (TreeNodeEventHandler) Events [TreeNodeDataBoundEvent];
  226. if (eh != null)
  227. eh (this, e);
  228. }
  229. }
  230. protected virtual void OnTreeNodeExpanded (TreeNodeEventArgs e)
  231. {
  232. if (Events != null) {
  233. TreeNodeEventHandler eh = (TreeNodeEventHandler) Events [TreeNodeExpandedEvent];
  234. if (eh != null)
  235. eh (this, e);
  236. }
  237. }
  238. protected virtual void OnTreeNodePopulate (TreeNodeEventArgs e)
  239. {
  240. if (Events != null) {
  241. TreeNodeEventHandler eh = (TreeNodeEventHandler) Events [TreeNodePopulateEvent];
  242. if (eh != null)
  243. eh (this, e);
  244. }
  245. }
  246. [Localizable (true)]
  247. public string CollapseImageToolTip {
  248. get { return ViewState.GetString ("CollapseImageToolTip", "Collapse {0}"); }
  249. set { ViewState["CollapseImageToolTip"] = value; }
  250. }
  251. [MonoTODO ("Implement support for this")]
  252. [WebCategory ("Behavior")]
  253. [WebSysDescription ("Whether the tree will automatically generate bindings.")]
  254. [DefaultValue (true)]
  255. public bool AutoGenerateDataBindings {
  256. get { return ViewState.GetBool ("AutoGenerateDataBindings", true); }
  257. set { ViewState["AutoGenerateDataBindings"] = value; }
  258. }
  259. [DefaultValue ("")]
  260. [WebSysDescription ("The url of the image to show when a node can be collapsed.")]
  261. [UrlProperty]
  262. [WebCategory ("Appearance")]
  263. [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
  264. public string CollapseImageUrl {
  265. get { return ViewState.GetString ("CollapseImageUrl", String.Empty); }
  266. set { ViewState["CollapseImageUrl"] = value; }
  267. }
  268. [WebCategory ("Data")]
  269. [PersistenceMode (PersistenceMode.InnerProperty)]
  270. [WebSysDescription ("Bindings for tree nodes.")]
  271. [Editor ("System.Web.UI.Design.WebControls.TreeViewBindingsEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
  272. [DefaultValue (null)]
  273. [MergablePropertyAttribute (false)]
  274. public TreeNodeBindingCollection DataBindings {
  275. get {
  276. if (dataBindings == null) {
  277. dataBindings = new TreeNodeBindingCollection ();
  278. if (IsTrackingViewState)
  279. ((IStateManager)dataBindings).TrackViewState();
  280. }
  281. return dataBindings;
  282. }
  283. }
  284. [WebCategory ("Behavior")]
  285. [WebSysDescription ("Whether the tree view can use client-side script to expand and collapse nodes.")]
  286. [Themeable (false)]
  287. [DefaultValue (true)]
  288. public bool EnableClientScript {
  289. get { return ViewState.GetBool ("EnableClientScript", true); }
  290. set { ViewState["EnableClientScript"] = value; }
  291. }
  292. [DefaultValue (-1)]
  293. [WebCategory ("Behavior")]
  294. [WebSysDescription ("The initial expand depth.")]
  295. [TypeConverter ("System.Web.UI.WebControls.TreeView+TreeViewExpandDepthConverter, " + Consts.AssemblySystem_Web)]
  296. public int ExpandDepth {
  297. get { return ViewState.GetInt ("ExpandDepth", -1); }
  298. set { ViewState["ExpandDepth"] = value; }
  299. }
  300. [Localizable (true)]
  301. public string ExpandImageToolTip {
  302. get { return ViewState.GetString ("ExpandImageToolTip", "Expand {0}"); }
  303. set { ViewState["ExpandImageToolTip"] = value; }
  304. }
  305. [DefaultValue ("")]
  306. [UrlProperty]
  307. [WebSysDescription ("The url of the image to show when a node can be expanded.")]
  308. [WebCategory ("Appearance")]
  309. [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
  310. public string ExpandImageUrl {
  311. get { return ViewState.GetString ("ExpandImageUrl", String.Empty); }
  312. set { ViewState["ExpandImageUrl"] = value; }
  313. }
  314. [PersistenceMode (PersistenceMode.InnerProperty)]
  315. [NotifyParentProperty (true)]
  316. [DefaultValue (null)]
  317. [WebCategory ("Styles")]
  318. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  319. public Style HoverNodeStyle {
  320. get {
  321. if (hoverNodeStyle == null) {
  322. hoverNodeStyle = new Style();
  323. if (IsTrackingViewState)
  324. hoverNodeStyle.TrackViewState();
  325. }
  326. return hoverNodeStyle;
  327. }
  328. }
  329. [DefaultValue (TreeViewImageSet.Custom)]
  330. public TreeViewImageSet ImageSet {
  331. get { return (TreeViewImageSet)ViewState.GetInt ("ImageSet", (int)TreeViewImageSet.Custom); }
  332. set {
  333. if (!Enum.IsDefined (typeof (TreeViewImageSet), value))
  334. throw new ArgumentOutOfRangeException ();
  335. ViewState["ImageSet"] = value;
  336. }
  337. }
  338. [PersistenceMode (PersistenceMode.InnerProperty)]
  339. [NotifyParentProperty (true)]
  340. [DefaultValue (null)]
  341. [WebCategory ("Styles")]
  342. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  343. public TreeNodeStyle LeafNodeStyle {
  344. get {
  345. if (leafNodeStyle == null) {
  346. leafNodeStyle = new TreeNodeStyle ();
  347. if (IsTrackingViewState)
  348. leafNodeStyle.TrackViewState();
  349. }
  350. return leafNodeStyle;
  351. }
  352. }
  353. [DefaultValue (null)]
  354. [WebCategory ("Styles")]
  355. [PersistenceMode (PersistenceMode.InnerProperty)]
  356. [Editor ("System.Web.UI.Design.WebControls.TreeNodeStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
  357. public TreeNodeStyleCollection LevelStyles {
  358. get {
  359. if (levelStyles == null) {
  360. levelStyles = new TreeNodeStyleCollection ();
  361. if (IsTrackingViewState)
  362. ((IStateManager)levelStyles).TrackViewState();
  363. }
  364. return levelStyles;
  365. }
  366. }
  367. [DefaultValue ("")]
  368. public string LineImagesFolder {
  369. get { return ViewState.GetString ("LineImagesFolder", String.Empty); }
  370. set { ViewState["LineImagesFolder"] = value; }
  371. }
  372. [DefaultValue (-1)]
  373. public int MaxDataBindDepth {
  374. get { return ViewState.GetInt ("MaxDataBindDepth", -1); }
  375. set { ViewState["MaxDataBindDepth"] = value; }
  376. }
  377. [DefaultValue (20)]
  378. public int NodeIndent {
  379. get { return ViewState.GetInt ("NodeIndent", 20); }
  380. set { ViewState["NodeIndent"] = value; }
  381. }
  382. [PersistenceMode (PersistenceMode.InnerProperty)]
  383. [Editor ("System.Web.UI.Design.WebControls.TreeNodeCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
  384. [DefaultValueAttribute (null)]
  385. [MergablePropertyAttribute (false)]
  386. public TreeNodeCollection Nodes {
  387. get {
  388. if (nodes == null) {
  389. nodes = new TreeNodeCollection (this);
  390. if (IsTrackingViewState)
  391. ((IStateManager)nodes).TrackViewState();
  392. }
  393. return nodes;
  394. }
  395. }
  396. [PersistenceMode (PersistenceMode.InnerProperty)]
  397. [NotifyParentProperty (true)]
  398. [DefaultValue (null)]
  399. [WebCategory ("Styles")]
  400. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  401. public TreeNodeStyle NodeStyle {
  402. get {
  403. if (nodeStyle == null) {
  404. nodeStyle = new TreeNodeStyle ();
  405. if (IsTrackingViewState)
  406. nodeStyle.TrackViewState();
  407. }
  408. return nodeStyle;
  409. }
  410. }
  411. [DefaultValue (false)]
  412. public bool NodeWrap {
  413. get { return ViewState.GetBool ("NodeWrap", false); }
  414. set { ViewState ["NodeWrap"] = value; }
  415. }
  416. [UrlProperty]
  417. [DefaultValue ("")]
  418. [WebSysDescription ("The url of the image to show for leaf nodes.")]
  419. [WebCategory ("Appearance")]
  420. [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
  421. public string NoExpandImageUrl {
  422. get { return ViewState.GetString ("NoExpandImageUrl", String.Empty); }
  423. set { ViewState ["NoExpandImageUrl"] = value; }
  424. }
  425. [PersistenceMode (PersistenceMode.InnerProperty)]
  426. [NotifyParentProperty (true)]
  427. [DefaultValue (null)]
  428. [WebCategory ("Styles")]
  429. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  430. public TreeNodeStyle ParentNodeStyle {
  431. get {
  432. if (parentNodeStyle == null) {
  433. parentNodeStyle = new TreeNodeStyle ();
  434. if (IsTrackingViewState)
  435. parentNodeStyle.TrackViewState();
  436. }
  437. return parentNodeStyle;
  438. }
  439. }
  440. [DefaultValue ('/')]
  441. public char PathSeparator {
  442. get { return ViewState.GetChar ("PathSeparator", '/'); }
  443. set { ViewState ["PathSeparator"] = value; }
  444. }
  445. [DefaultValue (true)]
  446. public bool PopulateNodesFromClient {
  447. get { return ViewState.GetBool ("PopulateNodesFromClient", true); }
  448. set { ViewState ["PopulateNodesFromClient"] = value; }
  449. }
  450. [PersistenceMode (PersistenceMode.InnerProperty)]
  451. [NotifyParentProperty (true)]
  452. [DefaultValue (null)]
  453. [WebCategory ("Styles")]
  454. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  455. public TreeNodeStyle RootNodeStyle {
  456. get {
  457. if (rootNodeStyle == null) {
  458. rootNodeStyle = new TreeNodeStyle ();
  459. if (IsTrackingViewState)
  460. rootNodeStyle.TrackViewState();
  461. }
  462. return rootNodeStyle;
  463. }
  464. }
  465. [PersistenceMode (PersistenceMode.InnerProperty)]
  466. [NotifyParentProperty (true)]
  467. [DefaultValue (null)]
  468. [WebCategory ("Styles")]
  469. [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
  470. public TreeNodeStyle SelectedNodeStyle {
  471. get {
  472. if (selectedNodeStyle == null) {
  473. selectedNodeStyle = new TreeNodeStyle ();
  474. if (IsTrackingViewState)
  475. selectedNodeStyle.TrackViewState();
  476. }
  477. return selectedNodeStyle;
  478. }
  479. }
  480. Style ControlLinkStyle {
  481. get {
  482. if (controlLinkStyle == null) {
  483. controlLinkStyle = new Style ();
  484. controlLinkStyle.AlwaysRenderTextDecoration = true;
  485. }
  486. return controlLinkStyle;
  487. }
  488. }
  489. Style NodeLinkStyle {
  490. get {
  491. if (nodeLinkStyle == null) {
  492. nodeLinkStyle = new Style ();
  493. }
  494. return nodeLinkStyle;
  495. }
  496. }
  497. Style RootNodeLinkStyle {
  498. get {
  499. if (rootNodeLinkStyle == null)
  500. rootNodeLinkStyle = new Style ();
  501. return rootNodeLinkStyle;
  502. }
  503. }
  504. Style ParentNodeLinkStyle {
  505. get {
  506. if (parentNodeLinkStyle == null)
  507. parentNodeLinkStyle = new Style ();
  508. return parentNodeLinkStyle;
  509. }
  510. }
  511. Style SelectedNodeLinkStyle {
  512. get {
  513. if (selectedNodeLinkStyle == null)
  514. selectedNodeLinkStyle = new Style ();
  515. return selectedNodeLinkStyle;
  516. }
  517. }
  518. Style LeafNodeLinkStyle {
  519. get {
  520. if (leafNodeLinkStyle == null)
  521. leafNodeLinkStyle = new Style ();
  522. return leafNodeLinkStyle;
  523. }
  524. }
  525. Style HoverNodeLinkStyle {
  526. get {
  527. if (hoverNodeLinkStyle == null)
  528. hoverNodeLinkStyle = new Style ();
  529. return hoverNodeLinkStyle;
  530. }
  531. }
  532. [DefaultValue (TreeNodeTypes.None)]
  533. public TreeNodeTypes ShowCheckBoxes {
  534. get { return (TreeNodeTypes)ViewState.GetInt ("ShowCheckBoxes", (int)TreeNodeTypes.None); }
  535. set {
  536. if ((int) value > 7)
  537. throw new ArgumentOutOfRangeException ();
  538. ViewState ["ShowCheckBoxes"] = value;
  539. }
  540. }
  541. [DefaultValue (true)]
  542. public bool ShowExpandCollapse {
  543. get { return ViewState.GetBool ("ShowExpandCollapse", true); }
  544. set { ViewState ["ShowExpandCollapse"] = value; }
  545. }
  546. [DefaultValue (false)]
  547. public bool ShowLines {
  548. get { return ViewState.GetBool ("ShowLines", false); }
  549. set { ViewState ["ShowLines"] = value; }
  550. }
  551. [Localizable (true)]
  552. public string SkipLinkText
  553. {
  554. get { return ViewState.GetString ("SkipLinkText", "Skip Navigation Links."); }
  555. set { ViewState ["SkipLinkText"] = value; }
  556. }
  557. [Browsable (false)]
  558. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  559. public TreeNode SelectedNode {
  560. get { return selectedNode; }
  561. }
  562. [Browsable (false)]
  563. [DefaultValue ("")]
  564. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  565. public string SelectedValue {
  566. get { return selectedNode != null ? selectedNode.Value : String.Empty; }
  567. }
  568. [DefaultValue ("")]
  569. public string Target {
  570. get { return ViewState.GetString ("Target", String.Empty); }
  571. set { ViewState ["Target"] = value; }
  572. }
  573. [MonoTODO ("why override?")]
  574. public override bool Visible
  575. {
  576. get { return base.Visible; }
  577. set { base.Visible = value; }
  578. }
  579. [Browsable (false)]
  580. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  581. public TreeNodeCollection CheckedNodes {
  582. get {
  583. TreeNodeCollection col = new TreeNodeCollection ();
  584. FindCheckedNodes (Nodes, col);
  585. return col;
  586. }
  587. }
  588. void FindCheckedNodes (TreeNodeCollection nodeList, TreeNodeCollection result)
  589. {
  590. foreach (TreeNode node in nodeList) {
  591. if (node.Checked)
  592. result.Add (node, false);
  593. FindCheckedNodes (node.ChildNodes, result);
  594. }
  595. }
  596. public void ExpandAll ()
  597. {
  598. foreach (TreeNode node in Nodes)
  599. node.ExpandAll ();
  600. }
  601. public void CollapseAll ()
  602. {
  603. foreach (TreeNode node in Nodes)
  604. node.CollapseAll ();
  605. }
  606. public TreeNode FindNode (string valuePath)
  607. {
  608. if (valuePath == null)
  609. throw new ArgumentNullException ("valuePath");
  610. string[] path = valuePath.Split (PathSeparator);
  611. int n = 0;
  612. TreeNodeCollection col = Nodes;
  613. bool foundBranch = true;
  614. while (col.Count > 0 && foundBranch) {
  615. foundBranch = false;
  616. foreach (TreeNode node in col) {
  617. if (node.Value == path [n]) {
  618. if (++n == path.Length)
  619. return node;
  620. col = node.ChildNodes;
  621. foundBranch = true;
  622. break;
  623. }
  624. }
  625. }
  626. return null;
  627. }
  628. ImageStyle GetImageStyle ()
  629. {
  630. if (ImageSet != TreeViewImageSet.Custom)
  631. return (ImageStyle) imageStyles [ImageSet];
  632. else
  633. return null;
  634. }
  635. protected override HtmlTextWriterTag TagKey {
  636. get { return HtmlTextWriterTag.Div; }
  637. }
  638. protected internal virtual TreeNode CreateNode ()
  639. {
  640. return new TreeNode (this);
  641. }
  642. public sealed override void DataBind ()
  643. {
  644. base.DataBind ();
  645. }
  646. protected void SetNodeDataBound (TreeNode node, bool dataBound)
  647. {
  648. node.SetDataBound (dataBound);
  649. }
  650. protected void SetNodeDataPath (TreeNode node, string dataPath)
  651. {
  652. node.SetDataPath (dataPath);
  653. }
  654. protected void SetNodeDataItem (TreeNode node, object dataItem)
  655. {
  656. node.SetDataItem (dataItem);
  657. }
  658. protected internal override void OnInit (EventArgs e)
  659. {
  660. base.OnInit (e);
  661. }
  662. internal void SetSelectedNode (TreeNode node, bool loading)
  663. {
  664. if (selectedNode == node)
  665. return;
  666. if (selectedNode != null)
  667. selectedNode.SelectedFlag = false;
  668. selectedNode = node;
  669. if (!loading)
  670. OnSelectedNodeChanged (new TreeNodeEventArgs (selectedNode));
  671. }
  672. internal void NotifyCheckChanged (TreeNode node)
  673. {
  674. OnTreeNodeCheckChanged (new TreeNodeEventArgs (node));
  675. }
  676. internal void NotifyExpandedChanged (TreeNode node)
  677. {
  678. if (node.Expanded.HasValue && node.Expanded.Value)
  679. OnTreeNodeExpanded (new TreeNodeEventArgs (node));
  680. else if (node.Expanded.HasValue && node.IsParentNode)
  681. OnTreeNodeCollapsed (new TreeNodeEventArgs (node));
  682. }
  683. internal void NotifyPopulateRequired (TreeNode node)
  684. {
  685. OnTreeNodePopulate (new TreeNodeEventArgs (node));
  686. }
  687. protected override void TrackViewState()
  688. {
  689. EnsureDataBound ();
  690. base.TrackViewState();
  691. if (hoverNodeStyle != null)
  692. hoverNodeStyle.TrackViewState();
  693. if (leafNodeStyle != null)
  694. leafNodeStyle.TrackViewState();
  695. if (levelStyles != null && levelStyles.Count > 0)
  696. ((IStateManager)levelStyles).TrackViewState();
  697. if (nodeStyle != null)
  698. nodeStyle.TrackViewState();
  699. if (parentNodeStyle != null)
  700. parentNodeStyle.TrackViewState();
  701. if (rootNodeStyle != null)
  702. rootNodeStyle.TrackViewState();
  703. if (selectedNodeStyle != null)
  704. selectedNodeStyle.TrackViewState();
  705. if (dataBindings != null)
  706. ((IStateManager)dataBindings).TrackViewState ();
  707. if (nodes != null)
  708. ((IStateManager)nodes).TrackViewState();;
  709. }
  710. protected override object SaveViewState()
  711. {
  712. object[] states = new object [10];
  713. states[0] = base.SaveViewState();
  714. states[1] = (hoverNodeStyle == null ? null : hoverNodeStyle.SaveViewState());
  715. states[2] = (leafNodeStyle == null ? null : leafNodeStyle.SaveViewState());
  716. states[3] = (levelStyles == null ? null : ((IStateManager)levelStyles).SaveViewState());
  717. states[4] = (nodeStyle == null ? null : nodeStyle.SaveViewState());
  718. states[5] = (parentNodeStyle == null ? null : parentNodeStyle.SaveViewState());
  719. states[6] = (rootNodeStyle == null ? null : rootNodeStyle.SaveViewState());
  720. states[7] = (selectedNodeStyle == null ? null : selectedNodeStyle.SaveViewState());
  721. states[8] = (dataBindings == null ? null : ((IStateManager)dataBindings).SaveViewState());
  722. states[9] = (nodes == null ? null : ((IStateManager)nodes).SaveViewState());
  723. for (int i = states.Length - 1; i >= 0; i--) {
  724. if (states [i] != null)
  725. return states;
  726. }
  727. return null;
  728. }
  729. protected override void LoadViewState (object savedState)
  730. {
  731. if (savedState == null)
  732. return;
  733. object [] states = (object []) savedState;
  734. base.LoadViewState (states[0]);
  735. if (states[1] != null)
  736. HoverNodeStyle.LoadViewState (states[1]);
  737. if (states[2] != null)
  738. LeafNodeStyle.LoadViewState(states[2]);
  739. if (states[3] != null)
  740. ((IStateManager)LevelStyles).LoadViewState(states[3]);
  741. if (states[4] != null)
  742. NodeStyle.LoadViewState(states[4]);
  743. if (states[5] != null)
  744. ParentNodeStyle.LoadViewState(states[5]);
  745. if (states[6] != null)
  746. RootNodeStyle.LoadViewState(states[6]);
  747. if (states[7] != null)
  748. SelectedNodeStyle.LoadViewState(states[7]);
  749. if (states[8] != null)
  750. ((IStateManager)DataBindings).LoadViewState(states[8]);
  751. if (states[9] != null)
  752. ((IStateManager)Nodes).LoadViewState(states[9]);
  753. }
  754. protected virtual void RaisePostBackEvent (string eventArgument)
  755. {
  756. ValidateEvent (UniqueID, eventArgument);
  757. string[] args = eventArgument.Split ('|');
  758. TreeNode node = FindNodeByPos (args[1]);
  759. if (node == null)
  760. return;
  761. if (args [0] == "sel")
  762. HandleSelectEvent (node);
  763. else if (args [0] == "ec")
  764. HandleExpandCollapseEvent (node);
  765. }
  766. void HandleSelectEvent (TreeNode node)
  767. {
  768. switch (node.SelectAction) {
  769. case TreeNodeSelectAction.Select:
  770. node.Select ();
  771. break;
  772. case TreeNodeSelectAction.Expand:
  773. node.Expand ();
  774. break;
  775. case TreeNodeSelectAction.SelectExpand:
  776. node.Select ();
  777. node.Expand ();
  778. break;
  779. }
  780. }
  781. void HandleExpandCollapseEvent (TreeNode node)
  782. {
  783. node.ToggleExpandState ();
  784. }
  785. protected virtual void RaisePostDataChangedEvent ()
  786. {
  787. }
  788. TreeNode MakeNodeTree (string[] args)
  789. {
  790. string[] segments = args [0].Split ('_');
  791. TreeNode ret = null, node;
  792. foreach (string seg in segments) {
  793. int idx = Int32.Parse (seg);
  794. node = new TreeNode (seg);
  795. if (ret != null) {
  796. ret.ChildNodes.Add (node);
  797. node.Index = idx;
  798. }
  799. ret = node;
  800. }
  801. ret.Value = args [1].Replace ("U+007C", "|");
  802. ret.ImageUrl = args [2].Replace ("U+007C", "|");
  803. ret.NavigateUrl = args [3].Replace ("U+007C", "|");
  804. ret.Target = args [4].Replace ("U+007C", "|");
  805. ret.Tree = this;
  806. NotifyPopulateRequired (ret);
  807. return ret;
  808. }
  809. string callbackResult;
  810. protected virtual void RaiseCallbackEvent (string eventArgs)
  811. {
  812. string[] args = eventArgs.Split ('|');
  813. RequiresDataBinding = true;
  814. EnsureDataBound ();
  815. TreeNode node = MakeNodeTree (args);
  816. ArrayList levelLines = new ArrayList ();
  817. TreeNode nd = node;
  818. while (nd != null) {
  819. int childCount = nd.Parent != null ? nd.Parent.ChildNodes.Count : Nodes.Count;
  820. levelLines.Insert (0, (nd.Index < childCount - 1) ? this : null);
  821. nd = nd.Parent;
  822. }
  823. StringWriter sw = new StringWriter ();
  824. HtmlTextWriter writer = new HtmlTextWriter (sw);
  825. EnsureStylesPrepared ();
  826. node.Expanded = true;
  827. int num = node.ChildNodes.Count;
  828. for (int n=0; n<num; n++)
  829. RenderNode (writer, node.ChildNodes [n], node.Depth + 1, levelLines, true, n<num-1);
  830. string res = sw.ToString ();
  831. callbackResult = res.Length > 0 ? res : "*";
  832. }
  833. protected virtual string GetCallbackResult ()
  834. {
  835. return callbackResult;
  836. }
  837. void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
  838. {
  839. RaisePostBackEvent (eventArgument);
  840. }
  841. bool IPostBackDataHandler.LoadPostData (string postDataKey, NameValueCollection postCollection)
  842. {
  843. return LoadPostData (postDataKey, postCollection);
  844. }
  845. void IPostBackDataHandler.RaisePostDataChangedEvent ()
  846. {
  847. RaisePostDataChangedEvent ();
  848. }
  849. void ICallbackEventHandler.RaiseCallbackEvent (string eventArgs)
  850. {
  851. RaiseCallbackEvent (eventArgs);
  852. }
  853. string ICallbackEventHandler.GetCallbackResult ()
  854. {
  855. return GetCallbackResult ();
  856. }
  857. protected override ControlCollection CreateControlCollection ()
  858. {
  859. return new EmptyControlCollection (this);
  860. }
  861. protected internal override void PerformDataBinding ()
  862. {
  863. base.PerformDataBinding ();
  864. InitializeDataBindings ();
  865. HierarchicalDataSourceView data = GetData (String.Empty);
  866. if (data == null)
  867. return;
  868. Nodes.Clear ();
  869. IHierarchicalEnumerable e = data.Select ();
  870. FillBoundChildrenRecursive (e, Nodes);
  871. }
  872. void FillBoundChildrenRecursive (IHierarchicalEnumerable hEnumerable, TreeNodeCollection nodeCollection)
  873. {
  874. if (hEnumerable == null)
  875. return;
  876. foreach (object obj in hEnumerable) {
  877. IHierarchyData hdata = hEnumerable.GetHierarchyData (obj);
  878. TreeNode child = new TreeNode ();
  879. nodeCollection.Add (child);
  880. child.Bind (hdata);
  881. OnTreeNodeDataBound (new TreeNodeEventArgs (child));
  882. if (MaxDataBindDepth >= 0 && child.Depth == MaxDataBindDepth)
  883. continue;
  884. if (hdata == null || !hdata.HasChildren)
  885. continue;
  886. IHierarchicalEnumerable e = hdata.GetChildren ();
  887. FillBoundChildrenRecursive (e, child.ChildNodes);
  888. }
  889. }
  890. protected virtual bool LoadPostData (string postDataKey, NameValueCollection postCollection)
  891. {
  892. bool res = false;
  893. if (EnableClientScript && PopulateNodesFromClient) {
  894. string states = postCollection [ClientID + "_PopulatedStates"];
  895. if (states != null) {
  896. foreach (string id in states.Split (postDataSplitChars, StringSplitOptions.RemoveEmptyEntries)) {
  897. TreeNode node = FindNodeByPos (id);
  898. if (node != null && node.PopulateOnDemand && !node.Populated) {
  899. Page page = Page;
  900. if (page != null && page.IsCallback)
  901. node.Populated = true; // Bug #492307
  902. else
  903. node.Populate (); // Bug #626829
  904. }
  905. }
  906. }
  907. res = true;
  908. }
  909. UnsetCheckStates (Nodes, postCollection);
  910. SetCheckStates (postCollection);
  911. if (EnableClientScript) {
  912. string states = postCollection [ClientID + "_ExpandStates"];
  913. if (states != null) {
  914. string[] ids = states.Split (postDataSplitChars, StringSplitOptions.RemoveEmptyEntries);
  915. UnsetExpandStates (Nodes, ids);
  916. SetExpandStates (ids);
  917. } else
  918. UnsetExpandStates (Nodes, new string[0]);
  919. res = true;
  920. }
  921. return res;
  922. }
  923. const string _OnPreRender_Script_Preamble =
  924. "var {0} = new Object ();\n" +
  925. "{0}.treeId = {1};\n" +
  926. "{0}.uid = {2};\n" +
  927. "{0}.showImage = {3};\n";
  928. const string _OnPreRender_Script_ShowExpandCollapse =
  929. "{0}.expandImage = {1};\n" +
  930. "{0}.collapseImage = {2};\n";
  931. const string _OnPreRender_Script_ShowExpandCollapse_Populate =
  932. "{0}.noExpandImage = {1};\n";
  933. const string _OnPreRender_Script_PopulateCallback =
  934. "{0}.form = {1};\n" +
  935. "{0}.PopulateNode = function (nodeId, nodeValue, nodeImageUrl, nodeNavigateUrl, nodeTarget) {{\n" +
  936. "\t{2}.__theFormPostData = \"\";\n" +
  937. "\t{2}.__theFormPostCollection = new Array ();\n" +
  938. "\t{2}.WebForm_InitCallback ();\n" +
  939. "\tTreeView_PopulateNode (this.uid, this.treeId, nodeId, nodeValue, nodeImageUrl, nodeNavigateUrl, nodeTarget)\n}};\n";
  940. const string _OnPreRender_Script_CallbackOptions =
  941. "{0}.populateFromClient = {1};\n" +
  942. "{0}.expandAlt = {2};\n" +
  943. "{0}.collapseAlt = {3};\n";
  944. const string _OnPreRender_Script_HoverStyle =
  945. "{0}.hoverClass = {1};\n" +
  946. "{0}.hoverLinkClass = {2};\n";
  947. protected internal override void OnPreRender (EventArgs e)
  948. {
  949. base.OnPreRender (e);
  950. Page page = Page;
  951. if (page != null) {
  952. if (IsEnabled)
  953. page.RegisterRequiresPostBack (this);
  954. if (EnableClientScript && !page.ClientScript.IsClientScriptIncludeRegistered (typeof(TreeView), "TreeView.js")) {
  955. string url = page.ClientScript.GetWebResourceUrl (typeof(TreeView), "TreeView.js");
  956. page.ClientScript.RegisterClientScriptInclude (typeof(TreeView), "TreeView.js", url);
  957. }
  958. }
  959. string ctree = ClientID + "_data";
  960. StringBuilder script = new StringBuilder ();
  961. script.AppendFormat (_OnPreRender_Script_Preamble,
  962. ctree,
  963. ClientScriptManager.GetScriptLiteral (ClientID),
  964. ClientScriptManager.GetScriptLiteral (UniqueID),
  965. ClientScriptManager.GetScriptLiteral (ShowExpandCollapse));
  966. if (ShowExpandCollapse) {
  967. ImageStyle imageStyle = GetImageStyle ();
  968. script.AppendFormat (_OnPreRender_Script_ShowExpandCollapse,
  969. ctree,
  970. ClientScriptManager.GetScriptLiteral (GetNodeImageUrl ("plus", imageStyle)),
  971. ClientScriptManager.GetScriptLiteral (GetNodeImageUrl ("minus", imageStyle)));
  972. if (PopulateNodesFromClient)
  973. script.AppendFormat (_OnPreRender_Script_ShowExpandCollapse_Populate,
  974. ctree,
  975. ClientScriptManager.GetScriptLiteral (GetNodeImageUrl ("noexpand", imageStyle)));
  976. }
  977. if (page != null) {
  978. script.AppendFormat (_OnPreRender_Script_PopulateCallback,
  979. ctree,
  980. page.theForm,
  981. page.WebFormScriptReference);
  982. // Page.ClientScript.GetCallbackEventReference (
  983. // "this.uid", "nodeId",
  984. // "TreeView_PopulateCallback",
  985. // "this.treeId + \" \" + nodeId", "TreeView_PopulateCallback", false));
  986. script.AppendFormat (_OnPreRender_Script_CallbackOptions,
  987. ctree,
  988. ClientScriptManager.GetScriptLiteral (PopulateNodesFromClient),
  989. ClientScriptManager.GetScriptLiteral (GetNodeImageToolTip (true, null)),
  990. ClientScriptManager.GetScriptLiteral (GetNodeImageToolTip (false, null)));
  991. if (!page.IsPostBack)
  992. SetNodesExpandedToDepthRecursive (Nodes);
  993. bool enableClientScript = EnableClientScript;
  994. if (enableClientScript) {
  995. page.ClientScript.RegisterHiddenField (ClientID + "_ExpandStates", GetExpandStates ());
  996. // Make sure the basic script infrastructure is rendered
  997. page.ClientScript.RegisterWebFormClientScript ();
  998. }
  999. if (enableClientScript && PopulateNodesFromClient)
  1000. page.ClientScript.RegisterHiddenField (ClientID + "_PopulatedStates", "|");
  1001. EnsureStylesPrepared ();
  1002. if (hoverNodeStyle != null) {
  1003. if (page.Header == null)
  1004. throw new InvalidOperationException ("Using TreeView.HoverNodeStyle requires Page.Header to be non-null (e.g. <head runat=\"server\" />).");
  1005. RegisterStyle (HoverNodeStyle, HoverNodeLinkStyle);
  1006. script.AppendFormat (_OnPreRender_Script_HoverStyle,
  1007. ctree,
  1008. ClientScriptManager.GetScriptLiteral (HoverNodeStyle.RegisteredCssClass),
  1009. ClientScriptManager.GetScriptLiteral (HoverNodeLinkStyle.RegisteredCssClass));
  1010. }
  1011. page.ClientScript.RegisterStartupScript (typeof(TreeView), this.UniqueID, script.ToString (), true);
  1012. script = null;
  1013. }
  1014. }
  1015. void EnsureStylesPrepared ()
  1016. {
  1017. if (stylesPrepared)
  1018. return;
  1019. stylesPrepared = true;
  1020. PrepareStyles ();
  1021. }
  1022. void PrepareStyles ()
  1023. {
  1024. // The order in which styles are defined matters when more than one class
  1025. // is assigned to an element
  1026. ControlLinkStyle.CopyTextStylesFrom (ControlStyle);
  1027. RegisterStyle (ControlLinkStyle);
  1028. if (nodeStyle != null)
  1029. RegisterStyle (NodeStyle, NodeLinkStyle);
  1030. if (rootNodeStyle != null)
  1031. RegisterStyle (RootNodeStyle, RootNodeLinkStyle);
  1032. if (parentNodeStyle != null)
  1033. RegisterStyle (ParentNodeStyle, ParentNodeLinkStyle);
  1034. if (leafNodeStyle != null)
  1035. RegisterStyle (LeafNodeStyle, LeafNodeLinkStyle);
  1036. if (levelStyles != null && levelStyles.Count > 0) {
  1037. levelLinkStyles = new List<Style> (levelStyles.Count);
  1038. foreach (Style style in levelStyles) {
  1039. Style linkStyle = new Style ();
  1040. levelLinkStyles.Add (linkStyle);
  1041. RegisterStyle (style, linkStyle);
  1042. }
  1043. }
  1044. if (selectedNodeStyle != null)
  1045. RegisterStyle (SelectedNodeStyle, SelectedNodeLinkStyle);
  1046. }
  1047. void SetNodesExpandedToDepthRecursive (TreeNodeCollection nodes)
  1048. {
  1049. foreach (TreeNode node in nodes) {
  1050. if (!node.Expanded.HasValue) {
  1051. if (ExpandDepth < 0 || node.Depth < ExpandDepth)
  1052. node.Expanded = true;
  1053. }
  1054. SetNodesExpandedToDepthRecursive (node.ChildNodes);
  1055. }
  1056. }
  1057. string IncrementStyleClassName ()
  1058. {
  1059. registeredStylesCounter++;
  1060. return ClientID + "_" + registeredStylesCounter;
  1061. }
  1062. void RegisterStyle (Style baseStyle, Style linkStyle)
  1063. {
  1064. linkStyle.CopyTextStylesFrom (baseStyle);
  1065. linkStyle.BorderStyle = BorderStyle.None;
  1066. linkStyle.AddCssClass (baseStyle.CssClass);
  1067. baseStyle.Font.Reset ();
  1068. RegisterStyle (linkStyle);
  1069. RegisterStyle (baseStyle);
  1070. }
  1071. void RegisterStyle (Style baseStyle)
  1072. {
  1073. if (Page.Header == null)
  1074. return;
  1075. string className = IncrementStyleClassName ().Trim ('_');
  1076. baseStyle.SetRegisteredCssClass (className);
  1077. Page.Header.StyleSheet.CreateStyleRule (baseStyle, this, "." + className);
  1078. }
  1079. string GetBindingKey (string dataMember, int depth)
  1080. {
  1081. return dataMember + " " + depth;
  1082. }
  1083. void InitializeDataBindings ()
  1084. {
  1085. if (dataBindings != null && dataBindings.Count > 0) {
  1086. bindings = new Hashtable ();
  1087. foreach (TreeNodeBinding bin in dataBindings) {
  1088. string key = GetBindingKey (bin.DataMember, bin.Depth);
  1089. if (!bindings.ContainsKey(key))
  1090. bindings [key] = bin;
  1091. }
  1092. } else
  1093. bindings = null;
  1094. }
  1095. internal TreeNodeBinding FindBindingForNode (string type, int depth)
  1096. {
  1097. if (bindings == null)
  1098. return null;
  1099. TreeNodeBinding bin = (TreeNodeBinding) bindings [GetBindingKey (type, depth)];
  1100. if (bin != null)
  1101. return bin;
  1102. bin = (TreeNodeBinding) bindings [GetBindingKey (type, -1)];
  1103. if (bin != null)
  1104. return bin;
  1105. bin = (TreeNodeBinding) bindings [GetBindingKey (String.Empty, depth)];
  1106. if (bin != null)
  1107. return bin;
  1108. return (TreeNodeBinding) bindings [GetBindingKey (String.Empty, -1)];
  1109. }
  1110. internal void DecorateNode(TreeNode node)
  1111. {
  1112. if (node == null)
  1113. return;
  1114. if (node.ImageUrl != null && node.ImageUrl.Length > 0)
  1115. return;
  1116. if (node.IsRootNode && rootNodeStyle != null) {
  1117. node.ImageUrl = rootNodeStyle.ImageUrl;
  1118. return;
  1119. }
  1120. if (node.IsParentNode && parentNodeStyle != null) {
  1121. node.ImageUrl = parentNodeStyle.ImageUrl;
  1122. return;
  1123. }
  1124. if (node.IsLeafNode && leafNodeStyle != null)
  1125. node.ImageUrl = leafNodeStyle.ImageUrl;
  1126. }
  1127. protected internal override void RenderContents (HtmlTextWriter writer)
  1128. {
  1129. SiteMapDataSource siteMap = GetDataSource () as SiteMapDataSource;
  1130. bool checkSitePath = IsBoundUsingDataSourceID && siteMap != null;
  1131. if (checkSitePath) {
  1132. IHierarchyData data = siteMap.Provider.CurrentNode;
  1133. if (data != null)
  1134. activeSiteMapPath = data.Path;
  1135. }
  1136. ArrayList levelLines = new ArrayList ();
  1137. int num = Nodes.Count;
  1138. for (int n=0; n<num; n++)
  1139. RenderNode (writer, Nodes [n], 0, levelLines, n>0, n<num-1);
  1140. }
  1141. protected override void AddAttributesToRender(HtmlTextWriter writer)
  1142. {
  1143. base.AddAttributesToRender (writer);
  1144. }
  1145. public override void RenderBeginTag (HtmlTextWriter writer)
  1146. {
  1147. string skipLinkText = SkipLinkText;
  1148. if (!String.IsNullOrEmpty (skipLinkText)) {
  1149. writer.AddAttribute (HtmlTextWriterAttribute.Href, "#" + ClientID + "_SkipLink");
  1150. writer.RenderBeginTag (HtmlTextWriterTag.A);
  1151. ClientScriptManager csm = new ClientScriptManager (null);
  1152. writer.AddAttribute (HtmlTextWriterAttribute.Alt, skipLinkText);
  1153. writer.AddAttribute (HtmlTextWriterAttribute.Src, csm.GetWebResourceUrl (typeof (SiteMapPath), "transparent.gif"));
  1154. writer.AddAttribute (HtmlTextWriterAttribute.Height, "0");
  1155. writer.AddAttribute (HtmlTextWriterAttribute.Width, "0");
  1156. writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0px");
  1157. writer.RenderBeginTag (HtmlTextWriterTag.Img);
  1158. writer.RenderEndTag (); // img
  1159. writer.RenderEndTag (); // a
  1160. }
  1161. base.RenderBeginTag (writer);
  1162. }
  1163. public override void RenderEndTag (HtmlTextWriter writer)
  1164. {
  1165. base.RenderEndTag (writer);
  1166. if (!String.IsNullOrEmpty (SkipLinkText)) {
  1167. writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_SkipLink");
  1168. writer.RenderBeginTag (HtmlTextWriterTag.A);
  1169. writer.RenderEndTag ();
  1170. }
  1171. }
  1172. void RenderNode (HtmlTextWriter writer, TreeNode node, int level, ArrayList levelLines, bool hasPrevious, bool hasNext)
  1173. {
  1174. // FIXME: disabled for now - needs closer investigation
  1175. //if (node.PopulateOnDemand && node.HadChildrenBeforePopulating)
  1176. // throw new InvalidOperationException ("PopulateOnDemand cannot be set to true on a node that already has children.");
  1177. DecorateNode(node);
  1178. string nodeImage;
  1179. bool clientExpand = EnableClientScript && Events [TreeNodeCollapsedEvent] == null && Events [TreeNodeExpandedEvent] == null;
  1180. ImageStyle imageStyle = GetImageStyle ();
  1181. bool renderChildNodes = node.Expanded.HasValue && node.Expanded.Value;
  1182. if (clientExpand && !renderChildNodes)
  1183. renderChildNodes = (!node.PopulateOnDemand || node.Populated);
  1184. bool hasChildNodes;
  1185. if (renderChildNodes)
  1186. hasChildNodes = node.ChildNodes.Count > 0;
  1187. else
  1188. hasChildNodes = (node.PopulateOnDemand && !node.Populated) || node.ChildNodes.Count > 0;
  1189. writer.AddAttribute (HtmlTextWriterAttribute.Cellpadding, "0", false);
  1190. writer.AddAttribute (HtmlTextWriterAttribute.Cellspacing, "0", false);
  1191. writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
  1192. writer.RenderBeginTag (HtmlTextWriterTag.Table);
  1193. Unit nodeSpacing = GetNodeSpacing (node);
  1194. #if !NET_4_0
  1195. if (nodeSpacing != Unit.Empty && (node.Depth > 0 || node.Index > 0))
  1196. RenderMenuItemSpacing (writer, nodeSpacing);
  1197. #endif
  1198. writer.RenderBeginTag (HtmlTextWriterTag.Tr);
  1199. // Vertical lines from previous levels
  1200. nodeImage = GetNodeImageUrl ("i", imageStyle);
  1201. for (int n=0; n<level; n++) {
  1202. writer.RenderBeginTag (HtmlTextWriterTag.Td);
  1203. writer.AddStyleAttribute (HtmlTextWriterStyle.Width, NodeIndent + "px");
  1204. writer.AddStyleAttribute (HtmlTextWriterStyle.Height, "1px");
  1205. writer.RenderBeginTag (HtmlTextWriterTag.Div);
  1206. if (ShowLines && levelLines [n] != null) {
  1207. writer.AddAttribute (HtmlTextWriterAttribute.Src, nodeImage);
  1208. writer.AddAttribute (HtmlTextWriterAttribute.Alt, String.Empty, false);
  1209. writer.RenderBeginTag (HtmlTextWriterTag.Img);
  1210. writer.RenderEndTag ();
  1211. }
  1212. writer.RenderEndTag ();
  1213. writer.RenderEndTag (); // TD
  1214. }
  1215. // Node image + line
  1216. bool showExpandCollapse = ShowExpandCollapse;
  1217. bool showLines = ShowLines;
  1218. if (showExpandCollapse || showLines) {
  1219. bool buttonImage = false;
  1220. string tooltip = String.Empty;
  1221. string shape = String.Empty;
  1222. if (showLines) {
  1223. if (hasPrevious && hasNext)
  1224. shape = "t";
  1225. else if (hasPrevious && !hasNext)
  1226. shape = "l";
  1227. else if (!hasPrevious && hasNext)
  1228. shape = "r";
  1229. else
  1230. shape = "dash";
  1231. }
  1232. if (showExpandCollapse) {
  1233. if (hasChildNodes) {
  1234. buttonImage = true;
  1235. if (node.Expanded.HasValue && node.Expanded.Value)
  1236. shape += "minus";
  1237. else
  1238. shape += "plus";
  1239. tooltip = GetNodeImageToolTip (!(node.Expanded.HasValue && node.Expanded.Value), node.Text);
  1240. } else if (!showLines)
  1241. shape = "noexpand";
  1242. }
  1243. if (!String.IsNullOrEmpty (shape)) {
  1244. nodeImage = GetNodeImageUrl (shape, imageStyle);
  1245. writer.RenderBeginTag (HtmlTextWriterTag.Td); // TD
  1246. if (buttonImage) {
  1247. if (!clientExpand || (!PopulateNodesFromClient && node.PopulateOnDemand && !node.Populated))
  1248. writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientEvent (node, "ec"));
  1249. else
  1250. writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientExpandEvent(node));
  1251. writer.RenderBeginTag (HtmlTextWriterTag.A); // Anchor
  1252. }
  1253. // tooltip is 'HtmlAttributeEncoded'
  1254. writer.AddAttribute (HtmlTextWriterAttribute.Alt, tooltip);
  1255. if (buttonImage && clientExpand)
  1256. writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, "img"));
  1257. writer.AddAttribute (HtmlTextWriterAttribute.Src, nodeImage);
  1258. if (buttonImage)
  1259. writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
  1260. writer.RenderBeginTag (HtmlTextWriterTag.Img);
  1261. writer.RenderEndTag ();
  1262. if (buttonImage)
  1263. writer.RenderEndTag (); // Anchor
  1264. writer.RenderEndTag (); // TD
  1265. }
  1266. }
  1267. // Node icon
  1268. string imageUrl = node.ImageUrl.Length > 0 ? ResolveClientUrl (node.ImageUrl) : null;
  1269. if (String.IsNullOrEmpty (imageUrl) && imageStyle != null) {
  1270. if (imageStyle.RootIcon != null && node.IsRootNode)
  1271. imageUrl = GetNodeIconUrl (imageStyle.RootIcon);
  1272. else if (imageStyle.ParentIcon != null && node.IsParentNode)
  1273. imageUrl = GetNodeIconUrl (imageStyle.ParentIcon);
  1274. else if (imageStyle.LeafIcon != null && node.IsLeafNode)
  1275. imageUrl = GetNodeIconUrl (imageStyle.LeafIcon);
  1276. }
  1277. if (level < LevelStyles.Count && LevelStyles [level].ImageUrl != null)
  1278. imageUrl = ResolveClientUrl (LevelStyles [level].ImageUrl);
  1279. if (!String.IsNullOrEmpty (imageUrl)) {
  1280. writer.RenderBeginTag (HtmlTextWriterTag.Td); // TD
  1281. #if NET_4_0
  1282. writer.AddAttribute (HtmlTextWriterAttribute.Tabindex, "-1");
  1283. #endif
  1284. BeginNodeTag (writer, node, clientExpand);
  1285. writer.AddAttribute (HtmlTextWriterAttribute.Src, imageUrl);
  1286. writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
  1287. writer.AddAttribute (HtmlTextWriterAttribute.Alt, node.ImageToolTip);
  1288. writer.RenderBeginTag (HtmlTextWriterTag.Img);
  1289. writer.RenderEndTag (); // IMG
  1290. writer.RenderEndTag (); // style tag
  1291. writer.RenderEndTag (); // TD
  1292. }
  1293. if (!NodeWrap)
  1294. writer.AddStyleAttribute (HtmlTextWriterStyle.WhiteSpace, "nowrap");
  1295. bool nodeIsSelected = node == SelectedNode && selectedNodeStyle != null;
  1296. if (!nodeIsSelected && selectedNodeStyle != null) {
  1297. if (!String.IsNullOrEmpty (activeSiteMapPath))
  1298. nodeIsSelected = String.Compare (activeSiteMapPath, node.NavigateUrl, RuntimeHelpers.StringComparison) == 0;
  1299. }
  1300. AddNodeStyle (writer, node, level, nodeIsSelected);
  1301. if (EnableClientScript) {
  1302. writer.AddAttribute ("onmouseout", "TreeView_UnhoverNode(this)", false);
  1303. writer.AddAttribute ("onmouseover", "TreeView_HoverNode('" + ClientID + "', this)");
  1304. }
  1305. writer.RenderBeginTag (HtmlTextWriterTag.Td); // TD
  1306. // Checkbox
  1307. if (node.ShowCheckBoxInternal) {
  1308. writer.AddAttribute (HtmlTextWriterAttribute.Name, ClientID + "_cs_" + node.Path);
  1309. writer.AddAttribute (HtmlTextWriterAttribute.Type, "checkbox", false);
  1310. #if NET_4_0
  1311. string str = node.ToolTip;
  1312. if (!String.IsNullOrEmpty (str))
  1313. writer.AddAttribute (HtmlTextWriterAttribute.Title, str);
  1314. #else
  1315. writer.AddAttribute (HtmlTextWriterAttribute.Title, node.Text);
  1316. #endif
  1317. if (node.Checked)
  1318. writer.AddAttribute (HtmlTextWriterAttribute.Checked, "checked", false);
  1319. writer.RenderBeginTag (HtmlTextWriterTag.Input); // INPUT
  1320. writer.RenderEndTag (); // INPUT
  1321. }
  1322. // Text
  1323. node.BeginRenderText (writer);
  1324. if (clientExpand)
  1325. writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, "txt"));
  1326. AddNodeLinkStyle (writer, node, level, nodeIsSelected);
  1327. BeginNodeTag (writer, node, clientExpand);
  1328. writer.Write (node.Text);
  1329. writer.RenderEndTag (); // style tag
  1330. node.EndRenderText (writer);
  1331. writer.RenderEndTag (); // TD
  1332. writer.RenderEndTag (); // TR
  1333. #if !NET_4_0
  1334. if (nodeSpacing != Unit.Empty)
  1335. RenderMenuItemSpacing (writer, nodeSpacing);
  1336. #endif
  1337. writer.RenderEndTag (); // TABLE
  1338. // Children
  1339. if (hasChildNodes) {
  1340. if (level >= levelLines.Count) {
  1341. if (hasNext)
  1342. levelLines.Add (this);
  1343. else
  1344. levelLines.Add (null);
  1345. } else {
  1346. if (hasNext)
  1347. levelLines [level] = this;
  1348. else
  1349. levelLines [level] = null;
  1350. }
  1351. if (clientExpand) {
  1352. if (!(node.Expanded.HasValue && node.Expanded.Value))
  1353. writer.AddStyleAttribute (HtmlTextWriterStyle.Display, "none");
  1354. else
  1355. writer.AddStyleAttribute (HtmlTextWriterStyle.Display, "block");
  1356. writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, null));
  1357. writer.RenderBeginTag (HtmlTextWriterTag.Span);
  1358. if (renderChildNodes) {
  1359. AddChildrenPadding (writer, node);
  1360. int num = node.ChildNodes.Count;
  1361. for (int n=0; n<num; n++)
  1362. RenderNode (writer, node.ChildNodes [n], level + 1, levelLines, true, n<num-1);
  1363. if (hasNext)
  1364. AddChildrenPadding (writer, node);
  1365. }
  1366. writer.RenderEndTag (); // SPAN
  1367. } else if (renderChildNodes) {
  1368. AddChildrenPadding (writer, node);
  1369. int num = node.ChildNodes.Count;
  1370. for (int n=0; n<num; n++)
  1371. RenderNode (writer, node.ChildNodes [n], level + 1, levelLines, true, n<num-1);
  1372. if (hasNext)
  1373. AddChildrenPadding (writer, node);
  1374. }
  1375. }
  1376. }
  1377. void AddChildrenPadding (HtmlTextWriter writer, TreeNode node)
  1378. {
  1379. int level = node.Depth;
  1380. Unit cnp = Unit.Empty;
  1381. if (levelStyles != null && level < levelStyles.Count)
  1382. cnp = levelStyles [level].ChildNodesPadding;
  1383. if (cnp.IsEmpty && nodeStyle != null)
  1384. cnp = nodeStyle.ChildNodesPadding;
  1385. double value;
  1386. if (cnp.IsEmpty || (value = cnp.Value) == 0 || cnp.Type != UnitType.Pixel)
  1387. return;
  1388. writer.RenderBeginTag (HtmlTextWriterTag.Table);
  1389. writer.AddAttribute (HtmlTextWriterAttribute.Height, ((int) value).ToString (), false);
  1390. writer.RenderBeginTag (HtmlTextWriterTag.Tr);
  1391. writer.RenderBeginTag (HtmlTextWriterTag.Td);
  1392. writer.RenderEndTag (); // td
  1393. writer.RenderEndTag (); // tr
  1394. writer.RenderEndTag (); // table
  1395. }
  1396. void RenderMenuItemSpacing (HtmlTextWriter writer, Unit itemSpacing)
  1397. {
  1398. #if !NET_4_0
  1399. writer.AddStyleAttribute (HtmlTextWriterStyle.Height, itemSpacing.ToString ());
  1400. #endif
  1401. writer.RenderBeginTag (HtmlTextWriterTag.Tr);
  1402. writer.RenderBeginTag (HtmlTextWriterTag.Td);
  1403. writer.RenderEndTag ();
  1404. writer.RenderEndTag ();
  1405. }
  1406. Unit GetNodeSpacing (TreeNode node)
  1407. {
  1408. if (node.Selected && selectedNodeStyle != null && selectedNodeStyle.NodeSpacing != Unit.Empty)
  1409. return selectedNodeStyle.NodeSpacing;
  1410. if (levelStyles != null && node.Depth < levelStyles.Count && levelStyles [node.Depth].NodeSpacing != Unit.Empty)
  1411. return levelStyles [node.Depth].NodeSpacing;
  1412. if (node.IsLeafNode) {
  1413. if (leafNodeStyle != null && leafNodeStyle.NodeSpacing != Unit.Empty)
  1414. return leafNodeStyle.NodeSpacing;
  1415. } else if (node.IsRootNode) {
  1416. if (rootNodeStyle != null && rootNodeStyle.NodeSpacing != Unit.Empty)
  1417. return rootNodeStyle.NodeSpacing;
  1418. } else if (node.IsParentNode) {
  1419. if (parentNodeStyle != null && parentNodeStyle.NodeSpacing != Unit.Empty)
  1420. return parentNodeStyle.NodeSpacing;
  1421. }
  1422. if (nodeStyle != null)
  1423. return nodeStyle.NodeSpacing;
  1424. else
  1425. return Unit.Empty;
  1426. }
  1427. void AddNodeStyle (HtmlTextWriter writer, TreeNode node, int level, bool nodeIsSelected)
  1428. {
  1429. TreeNodeStyle style = new TreeNodeStyle ();
  1430. if (Page.Header != null) {
  1431. // styles are registered
  1432. if (nodeStyle != null) {
  1433. #if NET_4_0
  1434. style.PrependCssClass (nodeStyle.RegisteredCssClass);
  1435. style.PrependCssClass (nodeStyle.CssClass);
  1436. #else
  1437. style.AddCssClass (nodeStyle.CssClass);
  1438. style.AddCssClass (nodeStyle.RegisteredCssClass);
  1439. #endif
  1440. }
  1441. if (node.IsLeafNode) {
  1442. if (leafNodeStyle != null) {
  1443. #if NET_4_0
  1444. style.PrependCssClass (leafNodeStyle.RegisteredCssClass);
  1445. style.PrependCssClass (leafNodeStyle.CssClass);
  1446. #else
  1447. style.AddCssClass (leafNodeStyle.CssClass);
  1448. style.AddCssClass (leafNodeStyle.RegisteredCssClass);
  1449. #endif
  1450. }
  1451. } else if (node.IsRootNode) {
  1452. if (rootNodeStyle != null) {
  1453. #if NET_4_0
  1454. style.PrependCssClass (rootNodeStyle.RegisteredCssClass);
  1455. style.PrependCssClass (rootNodeStyle.CssClass);
  1456. #else
  1457. style.AddCssClass (rootNodeStyle.CssClass);
  1458. style.AddCssClass (rootNodeStyle.RegisteredCssClass);
  1459. #endif
  1460. }
  1461. } else if (node.IsParentNode) {
  1462. if (parentNodeStyle != null) {
  1463. #if NET_4_0
  1464. style.AddCssClass (parentNodeStyle.RegisteredCssClass);
  1465. style.AddCssClass (parentNodeStyle.CssClass);
  1466. #else
  1467. style.AddCssClass (parentNodeStyle.CssClass);
  1468. style.AddCssClass (parentNodeStyle.RegisteredCssClass);
  1469. #endif
  1470. }
  1471. }
  1472. if (levelStyles != null && levelStyles.Count > level) {
  1473. #if NET_4_0
  1474. style.PrependCssClass (levelStyles [level].RegisteredCssClass);
  1475. style.PrependCssClass (levelStyles [level].CssClass);
  1476. #else
  1477. style.AddCssClass (levelStyles [level].CssClass);
  1478. style.AddCssClass (levelStyles [level].RegisteredCssClass);
  1479. #endif
  1480. }
  1481. if (nodeIsSelected) {
  1482. #if NET_4_0
  1483. style.AddCssClass (selectedNodeStyle.RegisteredCssClass);
  1484. style.AddCssClass (selectedNodeStyle.CssClass);
  1485. #else
  1486. style.AddCssClass (selectedNodeStyle.CssClass);
  1487. style.AddCssClass (selectedNodeStyle.RegisteredCssClass);
  1488. #endif
  1489. }
  1490. } else {
  1491. // styles are not registered
  1492. if (nodeStyle != null) {
  1493. style.CopyFrom (nodeStyle);
  1494. }
  1495. if (node.IsLeafNode) {
  1496. if (leafNodeStyle != null) {
  1497. style.CopyFrom (leafNodeStyle);
  1498. }
  1499. } else if (node.IsRootNode) {
  1500. if (rootNodeStyle != null) {
  1501. style.CopyFrom (rootNodeStyle);
  1502. }
  1503. } else if (node.IsParentNode) {
  1504. if (parentNodeStyle != null) {
  1505. style.CopyFrom (parentNodeStyle);
  1506. }
  1507. }
  1508. if (levelStyles != null && levelStyles.Count > level)
  1509. style.CopyFrom (levelStyles [level]);
  1510. if (nodeIsSelected)
  1511. style.CopyFrom (selectedNodeStyle);
  1512. }
  1513. style.AddAttributesToRender (writer);
  1514. }
  1515. void AddNodeLinkStyle (HtmlTextWriter writer, TreeNode node, int level, bool nodeIsSelected)
  1516. {
  1517. Style style = new Style ();
  1518. #if NET_4_0
  1519. bool addBorderStyle = false;
  1520. #endif
  1521. if (Page.Header != null) {
  1522. // styles are registered
  1523. style.AddCssClass (ControlLinkStyle.RegisteredCssClass);
  1524. if (nodeStyle != null) {
  1525. style.AddCssClass (nodeLinkStyle.CssClass);
  1526. style.AddCssClass (nodeLinkStyle.RegisteredCssClass);
  1527. }
  1528. if (levelLinkStyles != null && levelLinkStyles.Count > level) {
  1529. style.AddCssClass (levelLinkStyles [level].CssClass);
  1530. style.AddCssClass (levelLinkStyles [level].RegisteredCssClass);
  1531. #if NET_4_0
  1532. addBorderStyle = true;
  1533. #endif
  1534. }
  1535. if (node.IsLeafNode) {
  1536. if (leafNodeStyle != null) {
  1537. style.AddCssClass (leafNodeLinkStyle.CssClass);
  1538. style.AddCssClass (leafNodeLinkStyle.RegisteredCssClass);
  1539. }
  1540. } else if (node.IsRootNode) {
  1541. if (rootNodeStyle != null) {
  1542. style.AddCssClass (rootNodeLinkStyle.CssClass);
  1543. style.AddCssClass (rootNodeLinkStyle.RegisteredCssClass);
  1544. }
  1545. } else if (node.IsParentNode) {
  1546. if (parentNodeStyle != null) {
  1547. style.AddCssClass (parentNodeLinkStyle.CssClass);
  1548. style.AddCssClass (parentNodeLinkStyle.RegisteredCssClass);
  1549. }
  1550. }
  1551. if (nodeIsSelected) {
  1552. style.AddCssClass (selectedNodeLinkStyle.CssClass);
  1553. style.AddCssClass (selectedNodeLinkStyle.RegisteredCssClass);
  1554. }
  1555. } else {
  1556. // styles are not registered
  1557. style.CopyFrom (ControlLinkStyle);
  1558. if (nodeStyle != null)
  1559. style.CopyFrom (nodeLinkStyle);
  1560. if (levelLinkStyles != null && levelLinkStyles.Count > level) {
  1561. style.CopyFrom (levelLinkStyles [level]);
  1562. #if NET_4_0
  1563. addBorderStyle = true;
  1564. #endif
  1565. }
  1566. if (node.IsLeafNode) {
  1567. if (node.IsLeafNode && leafNodeStyle != null)
  1568. style.CopyFrom (leafNodeLinkStyle);
  1569. } else if (node.IsRootNode) {
  1570. if (node.IsRootNode && rootNodeStyle != null)
  1571. style.CopyFrom (rootNodeLinkStyle);
  1572. } else if (node.IsParentNode) {
  1573. if (node.IsParentNode && parentNodeStyle != null)
  1574. style.CopyFrom (parentNodeLinkStyle);
  1575. }
  1576. if (nodeIsSelected)
  1577. style.CopyFrom (selectedNodeLinkStyle);
  1578. style.AlwaysRenderTextDecoration = true;
  1579. }
  1580. #if NET_4_0
  1581. if (addBorderStyle) {
  1582. // This appears not to come from any style. Instead, it's added
  1583. // whenever a level style is present.
  1584. writer.AddStyleAttribute (HtmlTextWriterStyle.BorderStyle, "none");
  1585. writer.AddStyleAttribute (HtmlTextWriterStyle.FontSize, "1em");
  1586. }
  1587. #endif
  1588. style.AddAttributesToRender (writer);
  1589. }
  1590. void BeginNodeTag (HtmlTextWriter writer, TreeNode node, bool clientExpand)
  1591. {
  1592. if(node.ToolTip.Length>0)
  1593. writer.AddAttribute (HtmlTextWriterAttribute.Title, node.ToolTip);
  1594. string navigateUrl = node.NavigateUrl;
  1595. if (!String.IsNullOrEmpty (navigateUrl)) {
  1596. string target = node.Target.Length > 0 ? node.Target : Target;
  1597. #if TARGET_J2EE
  1598. string navUrl = ResolveClientUrl (navigateUrl, String.Compare (target, "_blank", StringComparison.InvariantCultureIgnoreCase) != 0);
  1599. #else
  1600. string navUrl = ResolveClientUrl (navigateUrl);
  1601. #endif
  1602. writer.AddAttribute (HtmlTextWriterAttribute.Href, navUrl);
  1603. if (target.Length > 0)
  1604. writer.AddAttribute (HtmlTextWriterAttribute.Target, target);
  1605. writer.RenderBeginTag (HtmlTextWriterTag.A);
  1606. } else if (node.SelectAction != TreeNodeSelectAction.None) {
  1607. if (node.SelectAction == TreeNodeSelectAction.Expand && clientExpand)
  1608. writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientExpandEvent (node));
  1609. else
  1610. writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientEvent (node, "sel"));
  1611. writer.RenderBeginTag (HtmlTextWriterTag.A);
  1612. } else
  1613. writer.RenderBeginTag (HtmlTextWriterTag.Span);
  1614. }
  1615. string GetNodeImageToolTip (bool expand, string txt)
  1616. {
  1617. if (expand) {
  1618. string expandImageToolTip = ExpandImageToolTip;
  1619. if (!String.IsNullOrEmpty (expandImageToolTip))
  1620. return String.Format (expandImageToolTip, HttpUtility.HtmlAttributeEncode (txt));
  1621. else if (txt != null)
  1622. return "Expand " + HttpUtility.HtmlAttributeEncode (txt);
  1623. else
  1624. return "Expand {0}";
  1625. } else {
  1626. string collapseImageToolTip = CollapseImageToolTip;
  1627. if (!String.IsNullOrEmpty (collapseImageToolTip))
  1628. return String.Format (collapseImageToolTip, HttpUtility.HtmlAttributeEncode (txt));
  1629. else if (txt != null)
  1630. return "Collapse " + HttpUtility.HtmlAttributeEncode (txt);
  1631. else
  1632. return "Collapse {0}";
  1633. }
  1634. }
  1635. string GetNodeClientId (TreeNode node, string sufix)
  1636. {
  1637. return ClientID + "_" + node.Path + (sufix != null ? "_" + sufix : String.Empty);
  1638. }
  1639. string GetNodeImageUrl (string shape, ImageStyle imageStyle)
  1640. {
  1641. if (ShowLines) {
  1642. if (!String.IsNullOrEmpty (LineImagesFolder))
  1643. return ResolveClientUrl (LineImagesFolder + "/" + shape + ".gif");
  1644. } else {
  1645. if (imageStyle != null) {
  1646. if (shape == "plus") {
  1647. if (!String.IsNullOrEmpty (imageStyle.Expand))
  1648. return GetNodeIconUrl (imageStyle.Expand);
  1649. } else if (shape == "minus") {
  1650. if (!String.IsNullOrEmpty (imageStyle.Collapse))
  1651. return GetNodeIconUrl (imageStyle.Collapse);
  1652. } else if (shape == "noexpand") {
  1653. if (!String.IsNullOrEmpty (imageStyle.NoExpand))
  1654. return GetNodeIconUrl (imageStyle.NoExpand);
  1655. }
  1656. } else {
  1657. if (shape == "plus") {
  1658. if (!String.IsNullOrEmpty (ExpandImageUrl))
  1659. return ResolveClientUrl (ExpandImageUrl);
  1660. } else if (shape == "minus") {
  1661. if (!String.IsNullOrEmpty (CollapseImageUrl))
  1662. return ResolveClientUrl (CollapseImageUrl);
  1663. } else if (shape == "noexpand") {
  1664. if (!String.IsNullOrEmpty (NoExpandImageUrl))
  1665. return ResolveClientUrl (NoExpandImageUrl);
  1666. }
  1667. }
  1668. if (!String.IsNullOrEmpty (LineImagesFolder))
  1669. return ResolveClientUrl (LineImagesFolder + "/" + shape + ".gif");
  1670. }
  1671. return Page.ClientScript.GetWebResourceUrl (typeof (TreeView), "TreeView_" + shape + ".gif");
  1672. }
  1673. string GetNodeIconUrl (string icon)
  1674. {
  1675. return Page.ClientScript.GetWebResourceUrl (typeof (TreeView), icon + ".gif");
  1676. }
  1677. string GetClientEvent (TreeNode node, string ev)
  1678. {
  1679. return Page.ClientScript.GetPostBackClientHyperlink (this, ev + "|" + node.Path, true);
  1680. }
  1681. string GetClientExpandEvent (TreeNode node)
  1682. {
  1683. return String.Format ("javascript:TreeView_ToggleExpand ('{0}','{1}','{2}','{3}','{4}','{5}')",
  1684. ClientID,
  1685. node.Path,
  1686. HttpUtility.HtmlAttributeEncode (node.Value).Replace ("'", "\\'").Replace ("|","U+007C"),
  1687. HttpUtility.HtmlAttributeEncode (node.ImageUrl).Replace ("'", "\\'").Replace ("|","U+007c"),
  1688. HttpUtility.HtmlAttributeEncode (node.NavigateUrl).Replace ("'", "\\'").Replace ("|","U+007C"),
  1689. HttpUtility.HtmlAttributeEncode (node.Target).Replace ("'", "\\'").Replace ("|","U+007C"));
  1690. }
  1691. TreeNode FindNodeByPos (string path)
  1692. {
  1693. string[] indexes = path.Split ('_');
  1694. TreeNode node = null;
  1695. foreach (string index in indexes) {
  1696. int i = int.Parse (index);
  1697. if (node == null) {
  1698. if (i >= Nodes.Count) return null;
  1699. node = Nodes [i];
  1700. } else {
  1701. if (i >= node.ChildNodes.Count) return null;
  1702. node = node.ChildNodes [i];
  1703. }
  1704. }
  1705. return node;
  1706. }
  1707. void UnsetCheckStates (TreeNodeCollection col, NameValueCollection states)
  1708. {
  1709. foreach (TreeNode node in col) {
  1710. if (node.ShowCheckBoxInternal && node.Checked) {
  1711. if (states == null || states [ClientID + "_cs_" + node.Path] == null)
  1712. node.Checked = false;
  1713. }
  1714. if (node.HasChildData)
  1715. UnsetCheckStates (node.ChildNodes, states);
  1716. }
  1717. }
  1718. void SetCheckStates (NameValueCollection states)
  1719. {
  1720. if (states == null)
  1721. return;
  1722. string keyPrefix = ClientID + "_cs_";
  1723. foreach (string key in states) {
  1724. if (key.StartsWith (keyPrefix, StringComparison.Ordinal)) {
  1725. string id = key.Substring (keyPrefix.Length);
  1726. TreeNode node = FindNodeByPos (id);
  1727. if (node != null && !node.Checked)
  1728. node.Checked = true;
  1729. }
  1730. }
  1731. }
  1732. void UnsetExpandStates (TreeNodeCollection col, string[] states)
  1733. {
  1734. foreach (TreeNode node in col) {
  1735. if (node.Expanded.HasValue && node.Expanded.Value) {
  1736. bool expand = (Array.IndexOf (states, node.Path) != -1);
  1737. if (!expand) node.Expanded = false;
  1738. }
  1739. if (node.HasChildData)
  1740. UnsetExpandStates (node.ChildNodes, states);
  1741. }
  1742. }
  1743. void SetExpandStates (string[] states)
  1744. {
  1745. foreach (string id in states) {
  1746. if (String.IsNullOrEmpty (id))
  1747. continue;
  1748. TreeNode node = FindNodeByPos (id);
  1749. if (node != null)
  1750. node.Expanded = true;
  1751. }
  1752. }
  1753. string GetExpandStates ()
  1754. {
  1755. StringBuilder sb = new StringBuilder ("|");
  1756. foreach (TreeNode node in Nodes)
  1757. GetExpandStates (sb, node);
  1758. return sb.ToString ();
  1759. }
  1760. void GetExpandStates (StringBuilder sb, TreeNode node)
  1761. {
  1762. if (node.Expanded.HasValue && node.Expanded.Value) {
  1763. sb.Append (node.Path);
  1764. sb.Append ('|');
  1765. }
  1766. if (node.HasChildData) {
  1767. foreach (TreeNode child in node.ChildNodes)
  1768. GetExpandStates (sb, child);
  1769. }
  1770. }
  1771. }
  1772. }
  1773. #endif