2010-03-02 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.Web / System.Web.UI.WebControls / Menu.cs
blob6973243bcfc4754d0e67bbaea65d468a0e71cc24
1 //
2 // System.Web.UI.WebControls.Menu.cs
3 //
4 // Authors:
5 // Lluis Sanchez Gual (lluis@novell.com)
6 // Igor Zelmanovich (igorz@mainsoft.com)
7 //
8 // (C) 2004 Novell, Inc (http://www.novell.com)
9 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #if NET_2_0
34 using System;
35 using System.Collections;
36 using System.Text;
37 using System.ComponentModel;
38 using System.Web.UI;
39 using System.Web.Handlers;
40 using System.Collections.Specialized;
41 using System.IO;
42 using System.Drawing;
43 using System.Collections.Generic;
45 namespace System.Web.UI.WebControls
47 [DefaultEvent ("MenuItemClick")]
48 [ControlValueProperty ("SelectedValue")]
49 [Designer ("System.Web.UI.Design.WebControls.MenuDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
50 [SupportsEventValidation]
51 public class Menu : HierarchicalDataBoundControl, IPostBackEventHandler, INamingContainer
53 MenuItemStyle dynamicMenuItemStyle;
54 SubMenuStyle dynamicMenuStyle;
55 MenuItemStyle dynamicSelectedStyle;
56 MenuItemStyle staticMenuItemStyle;
57 SubMenuStyle staticMenuStyle;
58 MenuItemStyle staticSelectedStyle;
59 Style staticHoverStyle;
60 Style dynamicHoverStyle;
62 MenuItemStyleCollection levelMenuItemStyles;
63 MenuItemStyleCollection levelSelectedStyles;
64 SubMenuStyleCollection levelSubMenuStyles;
65 ITemplate staticItemTemplate;
66 ITemplate dynamicItemTemplate;
68 MenuItemCollection items;
69 MenuItemBindingCollection dataBindings;
70 MenuItem selectedItem;
71 string selectedItemPath;
72 Hashtable bindings;
74 Hashtable _menuItemControls;
75 bool _requiresChildControlsDataBinding;
76 SiteMapNode _currSiteMapNode;
77 int registeredStylesCounter = -1;
78 List<Style> levelSelectedLinkStyles;
79 List<Style> levelMenuItemLinkStyles;
80 Style popOutBoxStyle;
81 Style controlLinkStyle;
82 Style dynamicMenuItemLinkStyle;
83 Style staticMenuItemLinkStyle;
84 Style dynamicSelectedLinkStyle;
85 Style staticSelectedLinkStyle;
86 Style dynamicHoverLinkStyle;
87 Style staticHoverLinkStyle;
89 static readonly object MenuItemClickEvent = new object();
90 static readonly object MenuItemDataBoundEvent = new object();
92 public static readonly string MenuItemClickCommandName = "Click";
94 public event MenuEventHandler MenuItemClick {
95 add { Events.AddHandler (MenuItemClickEvent, value); }
96 remove { Events.RemoveHandler (MenuItemClickEvent, value); }
99 public event MenuEventHandler MenuItemDataBound {
100 add { Events.AddHandler (MenuItemDataBoundEvent, value); }
101 remove { Events.RemoveHandler (MenuItemDataBoundEvent, value); }
104 protected virtual void OnMenuItemClick (MenuEventArgs e)
106 if (Events != null) {
107 MenuEventHandler eh = (MenuEventHandler) Events [MenuItemClickEvent];
108 if (eh != null) eh (this, e);
112 protected virtual void OnMenuItemDataBound (MenuEventArgs e)
114 if (Events != null) {
115 MenuEventHandler eh = (MenuEventHandler) Events [MenuItemDataBoundEvent];
116 if (eh != null) eh (this, e);
120 [DefaultValueAttribute (null)]
121 [PersistenceMode (PersistenceMode.InnerProperty)]
122 [EditorAttribute ("System.Web.UI.Design.WebControls.MenuBindingsEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
123 [MergablePropertyAttribute (false)]
124 public MenuItemBindingCollection DataBindings {
125 get {
126 if (dataBindings == null) {
127 dataBindings = new MenuItemBindingCollection ();
128 if (IsTrackingViewState)
129 ((IStateManager)dataBindings).TrackViewState();
131 return dataBindings;
135 [DefaultValue (500)]
136 [ThemeableAttribute (false)]
137 public int DisappearAfter {
138 get {
139 object o = ViewState ["DisappearAfter"];
140 if (o != null) return (int)o;
141 return 500;
143 set {
144 ViewState["DisappearAfter"] = value;
148 [ThemeableAttribute (true)]
149 [DefaultValue ("")]
150 [UrlProperty]
151 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
152 public string DynamicBottomSeparatorImageUrl {
153 get {
154 object o = ViewState ["dbsiu"];
155 if (o != null) return (string)o;
156 return "";
158 set {
159 ViewState["dbsiu"] = value;
163 [DefaultValueAttribute ("")]
164 public string DynamicItemFormatString {
165 get {
166 object o = ViewState ["DynamicItemFormatString"];
167 if (o != null) return (string)o;
168 return "";
170 set {
171 ViewState["DynamicItemFormatString"] = value;
175 [DefaultValue ("")]
176 [UrlProperty]
177 [WebCategory ("Appearance")]
178 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
179 public string DynamicTopSeparatorImageUrl {
180 get {
181 object o = ViewState ["dtsiu"];
182 if (o != null) return (string)o;
183 return "";
185 set {
186 ViewState["dtsiu"] = value;
190 [DefaultValue ("")]
191 [UrlProperty]
192 [WebCategory ("Appearance")]
193 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
194 public string StaticBottomSeparatorImageUrl {
195 get {
196 object o = ViewState ["sbsiu"];
197 if (o != null) return (string)o;
198 return "";
200 set {
201 ViewState["sbsiu"] = value;
205 [DefaultValue ("")]
206 [UrlProperty]
207 [WebCategory ("Appearance")]
208 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
209 public string StaticTopSeparatorImageUrl {
210 get {
211 object o = ViewState ["stsiu"];
212 if (o != null) return (string)o;
213 return "";
215 set {
216 ViewState["stsiu"] = value;
220 [DefaultValue (Orientation.Vertical)]
221 public Orientation Orientation {
222 get {
223 object o = ViewState ["Orientation"];
224 if (o != null) return (Orientation) o;
225 return Orientation.Vertical;
227 set {
228 ViewState["Orientation"] = value;
232 [DefaultValue (1)]
233 [ThemeableAttribute (true)]
234 public int StaticDisplayLevels {
235 get {
236 object o = ViewState ["StaticDisplayLevels"];
237 if (o != null) return (int)o;
238 return 1;
240 set {
241 if (value < 1) throw new ArgumentOutOfRangeException ();
242 ViewState["StaticDisplayLevels"] = value;
246 [DefaultValueAttribute ("")]
247 public string StaticItemFormatString {
248 get {
249 object o = ViewState ["StaticItemFormatString"];
250 if (o != null) return (string)o;
251 return "";
253 set {
254 ViewState["StaticItemFormatString"] = value;
258 [DefaultValue (typeof (Unit), "16px")]
259 [ThemeableAttribute (true)]
260 public Unit StaticSubMenuIndent {
261 get {
262 object o = ViewState ["StaticSubMenuIndent"];
263 if (o != null) return (Unit)o;
264 return new Unit (16);
266 set {
267 ViewState["StaticSubMenuIndent"] = value;
271 [ThemeableAttribute (true)]
272 [DefaultValue (3)]
273 public int MaximumDynamicDisplayLevels {
274 get {
275 object o = ViewState ["MaximumDynamicDisplayLevels"];
276 if (o != null) return (int)o;
277 return 3;
279 set {
280 if (value < 0) throw new ArgumentOutOfRangeException ();
281 ViewState["MaximumDynamicDisplayLevels"] = value;
285 [DefaultValue (0)]
286 public int DynamicVerticalOffset {
287 get {
288 object o = ViewState ["DynamicVerticalOffset"];
289 if (o != null) return (int)o;
290 return 0;
292 set {
293 ViewState["DynamicVerticalOffset"] = value;
297 [DefaultValue (0)]
298 public int DynamicHorizontalOffset {
299 get {
300 object o = ViewState ["DynamicHorizontalOffset"];
301 if (o != null) return (int)o;
302 return 0;
304 set {
305 ViewState["DynamicHorizontalOffset"] = value;
309 [DefaultValue (true)]
310 public bool DynamicEnableDefaultPopOutImage {
311 get {
312 object o = ViewState ["dedpoi"];
313 if (o != null) return (bool)o;
314 return true;
316 set {
317 ViewState["dedpoi"] = value;
321 [DefaultValue (true)]
322 public bool StaticEnableDefaultPopOutImage {
323 get {
324 object o = ViewState ["sedpoi"];
325 if (o != null) return (bool)o;
326 return true;
328 set {
329 ViewState["sedpoi"] = value;
333 [DefaultValueAttribute (null)]
334 [PersistenceMode (PersistenceMode.InnerProperty)]
335 [Editor ("System.Web.UI.Design.MenuItemCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
336 [MergablePropertyAttribute (false)]
337 public MenuItemCollection Items {
338 get {
339 if (items == null) {
340 items = new MenuItemCollection (this);
341 if (IsTrackingViewState)
342 ((IStateManager)items).TrackViewState();
344 return items;
348 [DefaultValue ('/')]
349 public char PathSeparator {
350 get {
351 object o = ViewState ["PathSeparator"];
352 if(o != null) return (char)o;
353 return '/';
355 set {
356 ViewState ["PathSeparator"] = value;
360 [DefaultValue (false)]
361 public bool ItemWrap {
362 get {
363 object o = ViewState ["ItemWrap"];
364 if(o != null) return (bool)o;
365 return false;
367 set {
368 ViewState ["ItemWrap"] = value;
372 Style PopOutBoxStyle {
373 get {
374 if (popOutBoxStyle == null) {
375 popOutBoxStyle = new Style ();
376 popOutBoxStyle.BackColor = Color.White;
378 return popOutBoxStyle;
382 Style ControlLinkStyle {
383 get {
384 if (controlLinkStyle == null) {
385 controlLinkStyle = new Style ();
386 controlLinkStyle.AlwaysRenderTextDecoration = true;
388 return controlLinkStyle;
392 Style DynamicMenuItemLinkStyle {
393 get {
394 if (dynamicMenuItemLinkStyle == null) {
395 dynamicMenuItemLinkStyle = new Style ();
397 return dynamicMenuItemLinkStyle;
401 Style StaticMenuItemLinkStyle {
402 get {
403 if (staticMenuItemLinkStyle == null) {
404 staticMenuItemLinkStyle = new Style ();
406 return staticMenuItemLinkStyle;
410 Style DynamicSelectedLinkStyle {
411 get {
412 if (dynamicSelectedLinkStyle == null) {
413 dynamicSelectedLinkStyle = new Style ();
415 return dynamicSelectedLinkStyle;
419 Style StaticSelectedLinkStyle {
420 get {
421 if (staticSelectedLinkStyle == null) {
422 staticSelectedLinkStyle = new Style ();
424 return staticSelectedLinkStyle;
428 Style DynamicHoverLinkStyle {
429 get {
430 if (dynamicHoverLinkStyle == null) {
431 dynamicHoverLinkStyle = new Style ();
433 return dynamicHoverLinkStyle;
437 Style StaticHoverLinkStyle {
438 get {
439 if (staticHoverLinkStyle == null) {
440 staticHoverLinkStyle = new Style ();
442 return staticHoverLinkStyle;
446 [PersistenceMode (PersistenceMode.InnerProperty)]
447 [NotifyParentProperty (true)]
448 [DefaultValue (null)]
449 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
450 public MenuItemStyle DynamicMenuItemStyle {
451 get {
452 if (dynamicMenuItemStyle == null) {
453 dynamicMenuItemStyle = new MenuItemStyle ();
454 if (IsTrackingViewState)
455 dynamicMenuItemStyle.TrackViewState();
457 return dynamicMenuItemStyle;
461 [PersistenceMode (PersistenceMode.InnerProperty)]
462 [NotifyParentProperty (true)]
463 [DefaultValue (null)]
464 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
465 public MenuItemStyle DynamicSelectedStyle {
466 get {
467 if (dynamicSelectedStyle == null) {
468 dynamicSelectedStyle = new MenuItemStyle ();
469 if (IsTrackingViewState)
470 dynamicSelectedStyle.TrackViewState();
472 return dynamicSelectedStyle;
476 [PersistenceMode (PersistenceMode.InnerProperty)]
477 [NotifyParentProperty (true)]
478 [DefaultValue (null)]
479 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
480 public SubMenuStyle DynamicMenuStyle {
481 get {
482 if (dynamicMenuStyle == null) {
483 dynamicMenuStyle = new SubMenuStyle ();
484 if (IsTrackingViewState)
485 dynamicMenuStyle.TrackViewState();
487 return dynamicMenuStyle;
491 [PersistenceMode (PersistenceMode.InnerProperty)]
492 [NotifyParentProperty (true)]
493 [DefaultValue (null)]
494 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
495 public MenuItemStyle StaticMenuItemStyle {
496 get {
497 if (staticMenuItemStyle == null) {
498 staticMenuItemStyle = new MenuItemStyle ();
499 if (IsTrackingViewState)
500 staticMenuItemStyle.TrackViewState();
502 return staticMenuItemStyle;
506 [PersistenceMode (PersistenceMode.InnerProperty)]
507 [NotifyParentProperty (true)]
508 [DefaultValue (null)]
509 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
510 public MenuItemStyle StaticSelectedStyle {
511 get {
512 if (staticSelectedStyle == null) {
513 staticSelectedStyle = new MenuItemStyle ();
514 if (IsTrackingViewState)
515 staticSelectedStyle.TrackViewState();
517 return staticSelectedStyle;
521 [PersistenceMode (PersistenceMode.InnerProperty)]
522 [NotifyParentProperty (true)]
523 [DefaultValue (null)]
524 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
525 public SubMenuStyle StaticMenuStyle {
526 get {
527 if (staticMenuStyle == null) {
528 staticMenuStyle = new SubMenuStyle ();
529 if (IsTrackingViewState)
530 staticMenuStyle.TrackViewState();
532 return staticMenuStyle;
536 [DefaultValue (null)]
537 [PersistenceMode (PersistenceMode.InnerProperty)]
538 [Editor ("System.Web.UI.Design.WebControls.MenuItemStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
539 public MenuItemStyleCollection LevelMenuItemStyles {
540 get {
541 if (levelMenuItemStyles == null) {
542 levelMenuItemStyles = new MenuItemStyleCollection ();
543 if (IsTrackingViewState)
544 ((IStateManager)levelMenuItemStyles).TrackViewState();
546 return levelMenuItemStyles;
550 [DefaultValue (null)]
551 [PersistenceMode (PersistenceMode.InnerProperty)]
552 [Editor ("System.Web.UI.Design.WebControls.MenuItemStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
553 public MenuItemStyleCollection LevelSelectedStyles {
554 get {
555 if (levelSelectedStyles == null) {
556 levelSelectedStyles = new MenuItemStyleCollection ();
557 if (IsTrackingViewState)
558 ((IStateManager)levelSelectedStyles).TrackViewState();
560 return levelSelectedStyles;
564 [DefaultValue (null)]
565 [PersistenceMode (PersistenceMode.InnerProperty)]
566 [Editor ("System.Web.UI.Design.WebControls.SubMenuStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
567 public SubMenuStyleCollection LevelSubMenuStyles {
568 get {
569 if (levelSubMenuStyles == null) {
570 levelSubMenuStyles = new SubMenuStyleCollection ();
571 if (IsTrackingViewState)
572 ((IStateManager)levelSubMenuStyles).TrackViewState();
574 return levelSubMenuStyles;
578 [PersistenceMode (PersistenceMode.InnerProperty)]
579 [NotifyParentProperty (true)]
580 [DefaultValue (null)]
581 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
582 public Style DynamicHoverStyle {
583 get {
584 if (dynamicHoverStyle == null) {
585 dynamicHoverStyle = new Style ();
586 if (IsTrackingViewState)
587 dynamicHoverStyle.TrackViewState();
589 return dynamicHoverStyle;
593 [PersistenceMode (PersistenceMode.InnerProperty)]
594 [NotifyParentProperty (true)]
595 [DefaultValue (null)]
596 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
597 public Style StaticHoverStyle {
598 get {
599 if (staticHoverStyle == null) {
600 staticHoverStyle = new Style ();
601 if (IsTrackingViewState)
602 staticHoverStyle.TrackViewState();
604 return staticHoverStyle;
608 [DefaultValue ("")]
609 [UrlProperty]
610 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
611 public string ScrollDownImageUrl {
612 get {
613 object o = ViewState ["sdiu"];
614 if (o != null) return (string)o;
615 return "";
617 set {
618 ViewState["sdiu"] = value;
622 [DefaultValue ("")]
623 [UrlProperty]
624 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
625 public string ScrollUpImageUrl {
626 get {
627 object o = ViewState ["suiu"];
628 if (o != null) return (string)o;
629 return "";
631 set {
632 ViewState["suiu"] = value;
636 [Localizable (true)]
637 public string ScrollDownText {
638 get {
639 object o = ViewState ["ScrollDownText"];
640 if (o != null) return (string) o;
641 return Locale.GetText ("Scroll down");
643 set {
644 ViewState["ScrollDownText"] = value;
648 [Localizable (true)]
649 public string ScrollUpText {
650 get {
651 object o = ViewState ["ScrollUpText"];
652 if (o != null) return (string) o;
653 return Locale.GetText ("Scroll up");
655 set {
656 ViewState["ScrollUpText"] = value;
660 public string DynamicPopOutImageTextFormatString
664 object o = ViewState ["dpoitf"];
665 if (o != null) return (string) o;
666 return Locale.GetText ("Expand {0}");
670 ViewState ["dpoitf"] = value;
675 [DefaultValue ("")]
676 [UrlProperty]
677 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
678 public string DynamicPopOutImageUrl {
679 get {
680 object o = ViewState ["dpoiu"];
681 if (o != null) return (string)o;
682 return "";
684 set {
685 ViewState["dpoiu"] = value;
689 public string StaticPopOutImageTextFormatString
693 object o = ViewState ["spoitf"];
694 if (o != null) return (string) o;
695 return Locale.GetText ("Expand {0}");
699 ViewState ["spoitf"] = value;
704 [DefaultValue ("")]
705 [UrlProperty]
706 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
707 public string StaticPopOutImageUrl {
708 get {
709 object o = ViewState ["spoiu"];
710 if (o != null) return (string)o;
711 return "";
713 set {
714 ViewState["spoiu"] = value;
718 [DefaultValue ("")]
719 public string Target {
720 get {
721 object o = ViewState ["Target"];
722 if (o != null) return (string) o;
723 return "";
725 set {
726 ViewState["Target"] = value;
730 [DefaultValue (null)]
731 [TemplateContainer (typeof(MenuItemTemplateContainer), BindingDirection.OneWay)]
732 [PersistenceMode (PersistenceMode.InnerProperty)]
733 [Browsable (false)]
734 public ITemplate StaticItemTemplate {
735 get { return staticItemTemplate; }
736 set { staticItemTemplate = value; }
739 [DefaultValue (null)]
740 [TemplateContainer (typeof(MenuItemTemplateContainer), BindingDirection.OneWay)]
741 [PersistenceMode (PersistenceMode.InnerProperty)]
742 [Browsable (false)]
743 public ITemplate DynamicItemTemplate {
744 get { return dynamicItemTemplate; }
745 set { dynamicItemTemplate = value; }
748 [Browsable (false)]
749 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
750 public MenuItem SelectedItem {
751 get {
752 if (selectedItem == null && selectedItemPath != null) {
753 selectedItem = FindItemByPos (selectedItemPath);
756 return selectedItem;
760 [Browsable (false)]
761 [DefaultValue ("")]
762 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
763 public string SelectedValue {
764 get { return selectedItem != null ? selectedItem.Value : ""; }
767 [Localizable (true)]
768 public string SkipLinkText
770 get {
771 object o = ViewState ["SkipLinkText"];
772 if (o != null)
773 return (string) o;
774 return "Skip Navigation Links";
776 set {
777 ViewState ["SkipLinkText"] = value;
782 internal void SetSelectedItem (MenuItem item)
784 if (selectedItem == item) return;
785 selectedItem = item;
786 selectedItemPath = item.Path;
789 public MenuItem FindItem (string valuePath)
791 if (valuePath == null) throw new ArgumentNullException ("valuePath");
792 string[] path = valuePath.Split (PathSeparator);
793 int n = 0;
794 MenuItemCollection col = Items;
795 bool foundBranch = true;
796 while (col.Count > 0 && foundBranch) {
797 foundBranch = false;
798 foreach (MenuItem item in col) {
799 if (item.Value == path [n]) {
800 if (++n == path.Length) return item;
801 col = item.ChildItems;
802 foundBranch = true;
803 break;
807 return null;
810 string GetBindingKey (string dataMember, int depth)
812 return dataMember + " " + depth;
815 internal MenuItemBinding FindBindingForItem (string type, int depth)
817 if (bindings == null) return null;
819 MenuItemBinding bin = (MenuItemBinding) bindings [GetBindingKey (type, depth)];
820 if (bin != null) return bin;
822 bin = (MenuItemBinding) bindings [GetBindingKey (type, -1)];
823 if (bin != null) return bin;
825 bin = (MenuItemBinding) bindings [GetBindingKey ("", depth)];
826 if (bin != null) return bin;
828 bin = (MenuItemBinding) bindings [GetBindingKey ("", -1)];
829 return bin;
832 protected internal override void PerformDataBinding ()
834 base.PerformDataBinding ();
836 // Do not attempt to bind data if there is no
837 // data source set.
838 if (!IsBoundUsingDataSourceID && (DataSource == null)) {
839 EnsureChildControlsDataBound ();
840 return;
843 InitializeDataBindings ();
845 HierarchicalDataSourceView data = GetData ("");
847 if (data == null) {
848 throw new InvalidOperationException ("No view returned by data source control.");
850 Items.Clear ();
851 IHierarchicalEnumerable e = data.Select ();
852 FillBoundChildrenRecursive (e, Items);
854 CreateChildControlsForItems ();
855 ChildControlsCreated = true;
857 EnsureChildControlsDataBound ();
860 void FillBoundChildrenRecursive (IHierarchicalEnumerable hEnumerable, MenuItemCollection itemCollection)
862 if (hEnumerable == null)
863 return;
864 foreach (object obj in hEnumerable) {
865 IHierarchyData hdata = hEnumerable.GetHierarchyData (obj);
866 MenuItem item = new MenuItem ();
867 itemCollection.Add (item);
868 item.Bind (hdata);
870 SiteMapNode siteMapNode = hdata as SiteMapNode;
871 if (siteMapNode != null) {
872 if (_currSiteMapNode == null)
873 _currSiteMapNode = siteMapNode.Provider.CurrentNode;
874 if (siteMapNode == _currSiteMapNode)
875 item.Selected = true;
878 OnMenuItemDataBound (new MenuEventArgs (item));
880 if (hdata == null || !hdata.HasChildren)
881 continue;
883 IHierarchicalEnumerable e = hdata.GetChildren ();
884 FillBoundChildrenRecursive (e, item.ChildItems);
888 protected void SetItemDataBound (MenuItem node, bool dataBound)
890 node.SetDataBound (dataBound);
893 protected void SetItemDataPath (MenuItem node, string dataPath)
895 node.SetDataPath (dataPath);
898 protected void SetItemDataItem (MenuItem node, object dataItem)
900 node.SetDataItem (dataItem);
903 protected internal virtual void RaisePostBackEvent (string eventArgument)
905 ValidateEvent (UniqueID, eventArgument);
906 if (!Enabled)
907 return;
909 EnsureChildControls();
910 MenuItem item = FindItemByPos (eventArgument);
911 if (item == null) return;
912 item.Selected = true;
913 OnMenuItemClick (new MenuEventArgs (item));
916 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
918 RaisePostBackEvent (eventArgument);
921 MenuItem FindItemByPos (string path)
923 string[] indexes = path.Split ('_');
924 MenuItem item = null;
926 foreach (string index in indexes) {
927 int i = int.Parse (index);
928 if (item == null) {
929 if (i >= Items.Count) return null;
930 item = Items [i];
931 } else {
932 if (i >= item.ChildItems.Count) return null;
933 item = item.ChildItems [i];
936 return item;
939 protected override HtmlTextWriterTag TagKey {
940 get { return HtmlTextWriterTag.Table; }
943 protected override void TrackViewState()
945 EnsureDataBound ();
947 base.TrackViewState();
948 if (dataBindings != null) {
949 ((IStateManager)dataBindings).TrackViewState ();
951 if (items != null) {
952 ((IStateManager)items).TrackViewState();
954 if (dynamicMenuItemStyle != null)
955 dynamicMenuItemStyle.TrackViewState ();
956 if (dynamicMenuStyle != null)
957 dynamicMenuStyle.TrackViewState ();
958 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > 0)
959 ((IStateManager)levelMenuItemStyles).TrackViewState();
960 if (levelSelectedStyles != null && levelMenuItemStyles.Count > 0)
961 ((IStateManager)levelSelectedStyles).TrackViewState();
962 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0)
963 ((IStateManager)levelSubMenuStyles).TrackViewState();
964 if (dynamicSelectedStyle != null)
965 dynamicSelectedStyle.TrackViewState();
966 if (staticMenuItemStyle != null)
967 staticMenuItemStyle.TrackViewState ();
968 if (staticMenuStyle != null)
969 staticMenuStyle.TrackViewState ();
970 if (staticSelectedStyle != null)
971 staticSelectedStyle.TrackViewState();
972 if (staticHoverStyle != null)
973 staticHoverStyle.TrackViewState();
974 if (dynamicHoverStyle != null)
975 dynamicHoverStyle.TrackViewState();
978 protected override object SaveViewState()
980 object[] states = new object [14];
981 states[0] = base.SaveViewState ();
982 states[1] = dataBindings == null ? null : ((IStateManager)dataBindings).SaveViewState();
983 states[2] = items == null ? null : ((IStateManager)items).SaveViewState();
984 states[3] = dynamicMenuItemStyle == null ? null : dynamicMenuItemStyle.SaveViewState();
985 states[4] = dynamicMenuStyle == null ? null : dynamicMenuStyle.SaveViewState();
986 states[5] = levelMenuItemStyles == null ? null : ((IStateManager)levelMenuItemStyles).SaveViewState();
987 states[6] = levelSelectedStyles == null ? null : ((IStateManager)levelSelectedStyles).SaveViewState();
988 states[7] = dynamicSelectedStyle == null ? null : dynamicSelectedStyle.SaveViewState();
989 states[8] = (staticMenuItemStyle == null ? null : staticMenuItemStyle.SaveViewState());
990 states[9] = staticMenuStyle == null ? null : staticMenuStyle.SaveViewState();
991 states[10] = staticSelectedStyle == null ? null : staticSelectedStyle.SaveViewState();
992 states[11] = staticHoverStyle == null ? null : staticHoverStyle.SaveViewState();
993 states[12] = dynamicHoverStyle == null ? null : dynamicHoverStyle.SaveViewState();
994 states[13] = levelSubMenuStyles == null ? null : ((IStateManager)levelSubMenuStyles).SaveViewState();
996 for (int i = states.Length - 1; i >= 0; i--) {
997 if (states [i] != null)
998 return states;
1001 return null;
1004 protected override void LoadViewState (object savedState)
1006 if (savedState == null)
1007 return;
1009 object [] states = (object []) savedState;
1010 base.LoadViewState (states[0]);
1012 if (states[1] != null)
1013 ((IStateManager)DataBindings).LoadViewState(states[1]);
1014 if (states[2] != null)
1015 ((IStateManager)Items).LoadViewState(states[2]);
1016 if (states[3] != null)
1017 DynamicMenuItemStyle.LoadViewState (states[3]);
1018 if (states[4] != null)
1019 DynamicMenuStyle.LoadViewState (states[4]);
1020 if (states[5] != null)
1021 ((IStateManager)LevelMenuItemStyles).LoadViewState(states[5]);
1022 if (states[6] != null)
1023 ((IStateManager)LevelSelectedStyles).LoadViewState(states[6]);
1024 if (states[7] != null)
1025 DynamicSelectedStyle.LoadViewState (states[7]);
1026 if (states[8] != null)
1027 StaticMenuItemStyle.LoadViewState (states[8]);
1028 if (states[9] != null)
1029 StaticMenuStyle.LoadViewState (states[9]);
1030 if (states[10] != null)
1031 StaticSelectedStyle.LoadViewState (states[10]);
1032 if (states[11] != null)
1033 StaticHoverStyle.LoadViewState (states[11]);
1034 if (states[12] != null)
1035 DynamicHoverStyle.LoadViewState (states[12]);
1036 if (states[13] != null)
1037 ((IStateManager)LevelSubMenuStyles).LoadViewState(states[13]);
1040 protected internal override void OnInit (EventArgs e)
1042 Page.RegisterRequiresControlState (this);
1043 base.OnInit (e);
1046 protected internal override void LoadControlState (object ob)
1048 if (ob == null) return;
1049 object[] state = (object[]) ob;
1050 base.LoadControlState (state[0]);
1051 selectedItemPath = state[1] as string;
1054 protected internal override object SaveControlState ()
1056 object bstate = base.SaveControlState ();
1057 object mstate = selectedItemPath;
1059 if (bstate != null || mstate != null)
1060 return new object[] { bstate, mstate };
1061 else
1062 return null;
1065 protected internal override void CreateChildControls ()
1067 if (!IsBoundUsingDataSourceID && (DataSource == null)) {
1068 CreateChildControlsForItems ();
1070 else {
1071 EnsureDataBound ();
1075 void CreateChildControlsForItems () {
1076 Controls.Clear ();
1077 // Check for HasChildViewState to avoid unnecessary calls to ClearChildViewState.
1078 if (HasChildViewState)
1079 ClearChildViewState ();
1080 _menuItemControls = new Hashtable ();
1081 CreateChildControlsForItems (Items);
1082 _requiresChildControlsDataBinding = true;
1085 void CreateChildControlsForItems (MenuItemCollection items ) {
1086 foreach (MenuItem item in items) {
1087 bool isDynamicItem = IsDynamicItem (item);
1088 if (isDynamicItem && dynamicItemTemplate != null) {
1089 MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
1090 dynamicItemTemplate.InstantiateIn (cter);
1091 _menuItemControls [item] = cter;
1092 Controls.Add (cter);
1094 else if (!isDynamicItem && staticItemTemplate != null) {
1095 MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
1096 staticItemTemplate.InstantiateIn (cter);
1097 _menuItemControls [item] = cter;
1098 Controls.Add (cter);
1100 if (item.HasChildData)
1101 CreateChildControlsForItems (item.ChildItems);
1105 protected override void EnsureDataBound ()
1107 base.EnsureDataBound ();
1109 EnsureChildControlsDataBound ();
1112 void EnsureChildControlsDataBound () {
1113 if (!_requiresChildControlsDataBinding)
1114 return;
1115 DataBindChildren ();
1116 _requiresChildControlsDataBinding = false;
1119 [MonoTODO ("Not implemented")]
1120 protected override IDictionary GetDesignModeState ()
1122 throw new NotImplementedException ();
1125 [MonoTODO ("Not implemented")]
1126 protected override void SetDesignModeState (IDictionary data)
1128 throw new NotImplementedException ();
1131 public override ControlCollection Controls {
1132 get { return base.Controls; }
1135 public sealed override void DataBind ()
1137 base.DataBind ();
1140 protected override bool OnBubbleEvent (object source, EventArgs args)
1142 if (!(args is CommandEventArgs))
1143 return false;
1145 MenuEventArgs menuArgs = args as MenuEventArgs;
1146 if (menuArgs != null && string.Equals (menuArgs.CommandName, MenuItemClickCommandName))
1147 OnMenuItemClick (menuArgs);
1148 return true;
1151 protected override void OnDataBinding (EventArgs e)
1153 EnsureChildControls ();
1154 base.OnDataBinding (e);
1157 const string onPreRenderScript = "var {0} = new Object ();\n{0}.webForm = {1};\n{0}.disappearAfter = {2};\n{0}.vertical = {3};";
1159 protected internal override void OnPreRender (EventArgs e)
1161 base.OnPreRender (e);
1163 if (!Page.ClientScript.IsClientScriptIncludeRegistered (typeof(Menu), "Menu.js")) {
1164 string url = Page.ClientScript.GetWebResourceUrl (typeof(Menu), "Menu.js");
1165 Page.ClientScript.RegisterClientScriptInclude (typeof(Menu), "Menu.js", url);
1168 string cmenu = ClientID + "_data";
1169 string script = String.Format (onPreRenderScript,
1170 cmenu,
1171 Page.IsMultiForm ? Page.theForm : "window",
1172 ClientScriptManager.GetScriptLiteral (DisappearAfter),
1173 ClientScriptManager.GetScriptLiteral (Orientation == Orientation.Vertical));
1175 if (DynamicHorizontalOffset != 0)
1176 script += String.Concat (cmenu, ".dho = ", ClientScriptManager.GetScriptLiteral (DynamicHorizontalOffset), ";\n");
1177 if (DynamicVerticalOffset != 0)
1178 script += String.Concat (cmenu, ".dvo = ", ClientScriptManager.GetScriptLiteral (DynamicVerticalOffset), ";\n");
1180 // The order in which styles are defined matters when more than one class
1181 // is assigned to an element
1182 RegisterStyle (PopOutBoxStyle);
1183 RegisterStyle (ControlStyle, ControlLinkStyle);
1185 if (staticMenuItemStyle != null)
1186 RegisterStyle (StaticMenuItemStyle, StaticMenuItemLinkStyle);
1188 if (staticMenuStyle != null)
1189 RegisterStyle (StaticMenuStyle);
1191 if (dynamicMenuItemStyle != null)
1192 RegisterStyle (DynamicMenuItemStyle, DynamicMenuItemLinkStyle);
1194 if (dynamicMenuStyle != null)
1195 RegisterStyle (DynamicMenuStyle);
1197 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > 0) {
1198 levelMenuItemLinkStyles = new List<Style> (levelMenuItemStyles.Count);
1199 foreach (Style style in levelMenuItemStyles) {
1200 Style linkStyle = new Style ();
1201 levelMenuItemLinkStyles.Add (linkStyle);
1202 RegisterStyle (style, linkStyle);
1206 if (levelSubMenuStyles != null)
1207 foreach (Style style in levelSubMenuStyles)
1208 RegisterStyle (style);
1210 if (staticSelectedStyle != null)
1211 RegisterStyle (staticSelectedStyle, StaticSelectedLinkStyle);
1213 if (dynamicSelectedStyle != null)
1214 RegisterStyle (dynamicSelectedStyle, DynamicSelectedLinkStyle);
1216 if (levelSelectedStyles != null && levelSelectedStyles.Count > 0) {
1217 levelSelectedLinkStyles = new List<Style> (levelSelectedStyles.Count);
1218 foreach (Style style in levelSelectedStyles) {
1219 Style linkStyle = new Style ();
1220 levelSelectedLinkStyles.Add (linkStyle);
1221 RegisterStyle (style, linkStyle);
1225 if (staticHoverStyle != null) {
1226 if (Page.Header == null)
1227 throw new InvalidOperationException ("Using Menu.StaticHoverStyle requires Page.Header to be non-null (e.g. <head runat=\"server\" />).");
1228 RegisterStyle (staticHoverStyle, StaticHoverLinkStyle);
1229 script += string.Concat (cmenu, ".staticHover = ", ClientScriptManager.GetScriptLiteral (staticHoverStyle.RegisteredCssClass), ";\n");
1230 script += string.Concat (cmenu, ".staticLinkHover = ", ClientScriptManager.GetScriptLiteral (StaticHoverLinkStyle.RegisteredCssClass), ";\n");
1233 if (dynamicHoverStyle != null) {
1234 if (Page.Header == null)
1235 throw new InvalidOperationException ("Using Menu.DynamicHoverStyle requires Page.Header to be non-null (e.g. <head runat=\"server\" />).");
1236 RegisterStyle (dynamicHoverStyle, DynamicHoverLinkStyle);
1237 script += string.Concat (cmenu, ".dynamicHover = ", ClientScriptManager.GetScriptLiteral (dynamicHoverStyle.RegisteredCssClass), ";\n");
1238 script += string.Concat (cmenu, ".dynamicLinkHover = ", ClientScriptManager.GetScriptLiteral (DynamicHoverLinkStyle.RegisteredCssClass), ";\n");
1241 Page.ClientScript.RegisterWebFormClientScript ();
1242 Page.ClientScript.RegisterStartupScript (typeof(Menu), ClientID, script, true);
1246 void InitializeDataBindings () {
1247 if (dataBindings != null && dataBindings.Count > 0) {
1248 bindings = new Hashtable ();
1249 foreach (MenuItemBinding bin in dataBindings) {
1250 string key = GetBindingKey (bin.DataMember, bin.Depth);
1251 bindings [key] = bin;
1254 else
1255 bindings = null;
1258 string IncrementStyleClassName () {
1259 registeredStylesCounter++;
1260 return ClientID + "_" + registeredStylesCounter;
1263 void RegisterStyle (Style baseStyle, Style linkStyle) {
1264 linkStyle.CopyTextStylesFrom (baseStyle);
1265 linkStyle.BorderStyle = BorderStyle.None;
1266 RegisterStyle (linkStyle);
1267 RegisterStyle (baseStyle);
1270 void RegisterStyle (Style baseStyle)
1272 if (Page.Header == null)
1273 return;
1274 string className = IncrementStyleClassName ();
1275 baseStyle.SetRegisteredCssClass (className);
1276 Page.Header.StyleSheet.CreateStyleRule (baseStyle, this, "." + className);
1279 protected internal override void Render (HtmlTextWriter writer)
1281 if (Items.Count > 0)
1282 base.Render (writer);
1285 protected override void AddAttributesToRender (HtmlTextWriter writer)
1287 writer.AddAttribute ("cellpadding", "0", false);
1288 writer.AddAttribute ("cellspacing", "0", false);
1289 writer.AddAttribute ("border", "0", false);
1290 if (Page.Header != null) {
1291 // styles are registered
1292 if (staticMenuStyle != null) {
1293 AddCssClass (ControlStyle, staticMenuStyle.CssClass);
1294 AddCssClass (ControlStyle, staticMenuStyle.RegisteredCssClass);
1296 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0) {
1297 AddCssClass (ControlStyle, levelSubMenuStyles [0].CssClass);
1298 AddCssClass (ControlStyle, levelSubMenuStyles [0].RegisteredCssClass);
1301 else {
1302 // styles are not registered
1303 if (staticMenuStyle != null){
1304 ControlStyle.CopyFrom (staticMenuStyle);
1306 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0) {
1307 ControlStyle.CopyFrom (levelSubMenuStyles [0]);
1310 base.AddAttributesToRender (writer);
1313 void AddCssClass (Style style, string cssClass) {
1314 style.AddCssClass (cssClass);
1317 public override void RenderBeginTag (HtmlTextWriter writer)
1319 if (SkipLinkText != "") {
1320 System.Web.UI.HtmlControls.HtmlAnchor anchor = new System.Web.UI.HtmlControls.HtmlAnchor ();
1321 anchor.HRef = "#" + ClientID + "_SkipLink";
1323 Image img = new Image ();
1324 ClientScriptManager csm = new ClientScriptManager (null);
1325 img.ImageUrl = csm.GetWebResourceUrl (typeof (SiteMapPath), "transparent.gif");
1326 img.Attributes.Add ("height", "0");
1327 img.Attributes.Add ("width", "0");
1328 img.AlternateText = SkipLinkText;
1330 anchor.Controls.Add (img);
1331 anchor.Render (writer);
1333 base.RenderBeginTag (writer);
1336 public override void RenderEndTag (HtmlTextWriter writer)
1338 base.RenderEndTag (writer);
1340 if (StaticDisplayLevels == 1 && MaximumDynamicDisplayLevels > 0)
1341 RenderDynamicMenu (writer, Items);
1343 if (SkipLinkText != "") {
1344 System.Web.UI.HtmlControls.HtmlAnchor anchor = new System.Web.UI.HtmlControls.HtmlAnchor ();
1345 anchor.ID = ClientID + "_SkipLink";
1346 anchor.Render (writer);
1350 protected internal override void RenderContents (HtmlTextWriter writer)
1352 RenderMenuBody (writer, Items, Orientation == Orientation.Vertical, false, false);
1355 void RenderDynamicMenu (HtmlTextWriter writer, MenuItemCollection items) {
1356 for (int n = 0; n < items.Count; n++) {
1357 if (DisplayChildren (items [n])) {
1358 RenderDynamicMenu (writer, items [n]);
1359 RenderDynamicMenu (writer, items [n].ChildItems);
1364 MenuRenderHtmlTemplate _dynamicTemplate;
1365 MenuRenderHtmlTemplate GetDynamicMenuTemplate (MenuItem item)
1367 if (_dynamicTemplate != null)
1368 return _dynamicTemplate;
1370 _dynamicTemplate = new MenuRenderHtmlTemplate ();
1371 HtmlTextWriter writer = _dynamicTemplate.GetMenuTemplateWriter ();
1373 if (Page.Header != null) {
1374 writer.AddAttribute (HtmlTextWriterAttribute.Class, MenuRenderHtmlTemplate.GetMarker (0));
1376 else {
1377 writer.AddAttribute (HtmlTextWriterAttribute.Style, MenuRenderHtmlTemplate.GetMarker (0));
1380 writer.AddStyleAttribute ("visibility", "hidden");
1381 writer.AddStyleAttribute ("position", "absolute");
1382 writer.AddStyleAttribute ("z-index", "1");
1383 writer.AddStyleAttribute ("left", "0px");
1384 writer.AddStyleAttribute ("top", "0px");
1385 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (1));
1386 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1388 // Up button
1389 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (2));
1390 writer.AddStyleAttribute ("display", "block");
1391 writer.AddStyleAttribute ("text-align", "center");
1392 writer.AddAttribute ("onmouseover", string.Concat ("Menu_OverScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (3), "','u')"));
1393 writer.AddAttribute ("onmouseout", string.Concat ("Menu_OutScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (4), "','u')"));
1394 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1396 writer.AddAttribute ("src", MenuRenderHtmlTemplate.GetMarker (5)); //src
1397 writer.AddAttribute ("alt", MenuRenderHtmlTemplate.GetMarker (6)); //ScrollUpText
1398 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1399 writer.RenderEndTag (); // IMG
1401 writer.RenderEndTag (); // DIV scroll button
1403 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (7));
1404 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1405 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (8));
1406 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1408 // call of RenderMenu
1409 writer.Write (MenuRenderHtmlTemplate.GetMarker (9));
1411 writer.RenderEndTag (); // DIV Content
1412 writer.RenderEndTag (); // DIV Scroll container
1414 // Down button
1415 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (0));
1416 writer.AddStyleAttribute ("display", "block");
1417 writer.AddStyleAttribute ("text-align", "center");
1418 writer.AddAttribute ("onmouseover", string.Concat ("Menu_OverScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (1), "','d')"));
1419 writer.AddAttribute ("onmouseout", string.Concat ("Menu_OutScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (2), "','d')"));
1420 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1422 writer.AddAttribute ("src", MenuRenderHtmlTemplate.GetMarker (3)); //src
1423 writer.AddAttribute ("alt", MenuRenderHtmlTemplate.GetMarker (4)); //ScrollDownText
1424 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1425 writer.RenderEndTag (); // IMG
1427 writer.RenderEndTag (); // DIV scroll button
1429 writer.RenderEndTag (); // DIV menu
1431 _dynamicTemplate.Parse ();
1432 return _dynamicTemplate;
1435 void RenderDynamicMenu (HtmlTextWriter writer, MenuItem item)
1437 _dynamicTemplate = GetDynamicMenuTemplate (item);
1439 string idPrefix = ClientID + "_" + item.Path;
1440 string [] param = new string [9];
1441 param [0] = GetCssMenuStyle (true, item.Depth + 1);
1442 param [1] = idPrefix + "s";
1443 param [2] = idPrefix + "cu";
1444 param [3] = item.Path;
1445 param [4] = item.Path;
1446 param [5] = ScrollUpImageUrl != "" ? ScrollUpImageUrl : Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_up.gif");
1447 param [6] = ScrollUpText;
1448 param [7] = idPrefix + "cb";
1449 param [8] = idPrefix + "cc";
1451 _dynamicTemplate.RenderTemplate (writer, param, 0, param.Length);
1453 RenderMenu (writer, item.ChildItems, true, true, item.Depth + 1, false);
1455 string [] param2 = new string [5];
1456 param2 [0] = idPrefix + "cd";
1457 param2 [1] = item.Path;
1458 param2 [2] = item.Path;
1459 param2 [3] = ScrollDownImageUrl != "" ? ScrollDownImageUrl : Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_down.gif");
1460 param2 [4] = ScrollDownText;
1462 _dynamicTemplate.RenderTemplate (writer, param2, param.Length + 1, param2.Length);
1466 string GetCssMenuStyle (bool dynamic, int menuLevel)
1468 if (Page.Header != null) {
1469 // styles are registered
1470 StringBuilder sb = new StringBuilder ();
1472 if (!dynamic && staticMenuStyle != null) {
1473 sb.Append (staticMenuStyle.CssClass);
1474 sb.Append (' ');
1475 sb.Append (staticMenuStyle.RegisteredCssClass);
1477 if (dynamic && dynamicMenuStyle != null) {
1478 sb.Append (PopOutBoxStyle.RegisteredCssClass);
1479 sb.Append (' ');
1480 sb.Append (dynamicMenuStyle.CssClass);
1481 sb.Append (' ');
1482 sb.Append (dynamicMenuStyle.RegisteredCssClass);
1484 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
1485 sb.Append (levelSubMenuStyles [menuLevel].CssClass);
1486 sb.Append (' ');
1487 sb.Append (levelSubMenuStyles [menuLevel].RegisteredCssClass);
1489 return sb.ToString ();
1491 else {
1492 // styles are not registered
1493 SubMenuStyle style = new SubMenuStyle ();
1495 if (!dynamic && staticMenuStyle != null) {
1496 style.CopyFrom (staticMenuStyle);
1498 if (dynamic && dynamicMenuStyle != null) {
1499 style.CopyFrom (PopOutBoxStyle);
1500 style.CopyFrom (dynamicMenuStyle);
1502 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
1503 style.CopyFrom (levelSubMenuStyles [menuLevel]);
1505 return style.GetStyleAttributes (null).Value;
1509 void RenderMenuBeginTagAttributes (HtmlTextWriter writer, bool dynamic, int menuLevel) {
1510 writer.AddAttribute ("cellpadding", "0", false);
1511 writer.AddAttribute ("cellspacing", "0", false);
1512 writer.AddAttribute ("border", "0", false);
1514 if (!dynamic) {
1515 SubMenuStyle style = new SubMenuStyle ();
1516 FillMenuStyle (dynamic, menuLevel, style);
1517 style.AddAttributesToRender (writer);
1521 void FillMenuStyle (bool dynamic, int menuLevel, SubMenuStyle style) {
1522 if (Page.Header != null) {
1523 // styles are registered
1524 if (!dynamic && staticMenuStyle != null) {
1525 AddCssClass (style, staticMenuStyle.CssClass);
1526 AddCssClass (style, staticMenuStyle.RegisteredCssClass);
1528 if (dynamic && dynamicMenuStyle != null) {
1529 AddCssClass (style, dynamicMenuStyle.CssClass);
1530 AddCssClass (style, dynamicMenuStyle.RegisteredCssClass);
1532 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
1533 AddCssClass (style, levelSubMenuStyles [menuLevel].CssClass);
1534 AddCssClass (style, levelSubMenuStyles [menuLevel].RegisteredCssClass);
1537 else {
1538 // styles are not registered
1539 if (!dynamic && staticMenuStyle != null) {
1540 style.CopyFrom (staticMenuStyle);
1542 if (dynamic && dynamicMenuStyle != null) {
1543 style.CopyFrom (dynamicMenuStyle);
1545 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
1546 style.CopyFrom (levelSubMenuStyles [menuLevel]);
1551 void RenderMenu (HtmlTextWriter writer, MenuItemCollection items, bool vertical, bool dynamic, int menuLevel, bool notLast)
1553 RenderMenuBeginTag (writer, dynamic, menuLevel);
1554 RenderMenuBody (writer, items, vertical, dynamic, notLast);
1555 RenderMenuEndTag (writer);
1558 void RenderMenuBeginTag (HtmlTextWriter writer, bool dynamic, int menuLevel)
1560 RenderMenuBeginTagAttributes (writer, dynamic, menuLevel);
1561 writer.RenderBeginTag (HtmlTextWriterTag.Table);
1564 void RenderMenuEndTag (HtmlTextWriter writer)
1566 writer.RenderEndTag ();
1569 void RenderMenuBody (HtmlTextWriter writer, MenuItemCollection items, bool vertical, bool dynamic, bool notLast) {
1570 if (!vertical)
1571 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1573 int count = items.Count;
1574 for (int n = 0; n < count; n++) {
1575 MenuItem item = items [n];
1576 Adapters.MenuAdapter adapter = Adapter as Adapters.MenuAdapter;
1577 if (adapter != null)
1578 adapter.RenderItem (writer, item, n);
1579 else
1580 RenderMenuItem (writer, item, (n + 1 == count) ? notLast : true, n == 0);
1583 if (!vertical)
1584 writer.RenderEndTag (); // TR
1587 void RenderMenuItemSpacing (HtmlTextWriter writer, Unit itemSpacing, bool vertical) {
1588 if (vertical) {
1589 writer.AddStyleAttribute ("height", itemSpacing.ToString ());
1590 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1591 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1592 writer.RenderEndTag ();
1593 writer.RenderEndTag ();
1595 else {
1596 writer.AddStyleAttribute ("width", itemSpacing.ToString ());
1597 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1598 writer.RenderEndTag ();
1602 bool IsDynamicItem (MenuItem item) {
1603 return item.Depth + 1 > StaticDisplayLevels;
1606 bool DisplayChildren (MenuItem item) {
1607 return (item.Depth + 1 < StaticDisplayLevels + MaximumDynamicDisplayLevels) && item.ChildItems.Count > 0;
1610 internal void RenderItem (HtmlTextWriter writer, MenuItem item, int position) {
1611 // notLast should be true if item or any of its ancestors is not a
1612 // last child.
1613 bool notLast = false;
1614 MenuItem parent;
1615 MenuItem child = item;
1616 while (null != (parent = child.Parent)) {
1617 if (child.Index != parent.ChildItems.Count - 1) {
1618 notLast = true;
1619 break;
1621 child = parent;
1624 RenderMenuItem (writer, item, notLast, position == 0);
1627 void RenderMenuItem (HtmlTextWriter writer, MenuItem item, bool notLast, bool isFirst) {
1628 bool displayChildren = DisplayChildren (item);
1629 bool dynamicChildren = displayChildren && (item.Depth + 1 >= StaticDisplayLevels);
1630 bool isDynamicItem = IsDynamicItem (item);
1631 bool vertical = (Orientation == Orientation.Vertical) || isDynamicItem;
1633 Unit itemSpacing = GetItemSpacing (item, isDynamicItem);
1635 if (itemSpacing != Unit.Empty && (item.Depth > 0 || !isFirst))
1636 RenderMenuItemSpacing (writer, itemSpacing, vertical);
1638 if(!String.IsNullOrEmpty(item.ToolTip))
1639 writer.AddAttribute (HtmlTextWriterAttribute.Title, item.ToolTip);
1640 if (vertical)
1641 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1643 string parentId = isDynamicItem ? "'" + item.Parent.Path + "'" : "null";
1644 if (dynamicChildren) {
1645 writer.AddAttribute ("onmouseover",
1646 "javascript:Menu_OverItem ('" + ClientID + "','" + item.Path + "'," + parentId + ")");
1647 writer.AddAttribute ("onmouseout",
1648 "javascript:Menu_OutItem ('" + ClientID + "','" + item.Path + "')");
1649 } else if (isDynamicItem) {
1650 writer.AddAttribute ("onmouseover",
1651 "javascript:Menu_OverDynamicLeafItem ('" + ClientID + "','" + item.Path + "'," + parentId + ")");
1652 writer.AddAttribute ("onmouseout",
1653 "javascript:Menu_OutItem ('" + ClientID + "','" + item.Path + "'," + parentId + ")");
1654 } else {
1655 writer.AddAttribute ("onmouseover",
1656 "javascript:Menu_OverStaticLeafItem ('" + ClientID + "','" + item.Path + "')");
1657 writer.AddAttribute ("onmouseout",
1658 "javascript:Menu_OutItem ('" + ClientID + "','" + item.Path + "')");
1661 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1663 // Top separator image
1665 if (isDynamicItem && DynamicTopSeparatorImageUrl != "") {
1666 writer.AddAttribute ("src", ResolveClientUrl (DynamicTopSeparatorImageUrl));
1667 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1668 writer.RenderEndTag (); // IMG
1670 else if (!isDynamicItem && StaticTopSeparatorImageUrl != "") {
1671 writer.AddAttribute ("src", ResolveClientUrl (StaticTopSeparatorImageUrl));
1672 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1673 writer.RenderEndTag (); // IMG
1676 // Menu item box
1678 MenuItemStyle style = new MenuItemStyle ();
1679 if (Page.Header != null) {
1680 // styles are registered
1681 if (!isDynamicItem && staticMenuItemStyle != null) {
1682 AddCssClass (style, staticMenuItemStyle.CssClass);
1683 AddCssClass (style, staticMenuItemStyle.RegisteredCssClass);
1685 if (isDynamicItem && dynamicMenuItemStyle != null) {
1686 AddCssClass (style, dynamicMenuItemStyle.CssClass);
1687 AddCssClass (style, dynamicMenuItemStyle.RegisteredCssClass);
1689 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
1690 AddCssClass (style, levelMenuItemStyles [item.Depth].CssClass);
1691 AddCssClass (style, levelMenuItemStyles [item.Depth].RegisteredCssClass);
1693 if (item == SelectedItem) {
1694 if (!isDynamicItem && staticSelectedStyle != null) {
1695 AddCssClass (style, staticSelectedStyle.CssClass);
1696 AddCssClass (style, staticSelectedStyle.RegisteredCssClass);
1698 if (isDynamicItem && dynamicSelectedStyle != null) {
1699 AddCssClass (style, dynamicSelectedStyle.CssClass);
1700 AddCssClass (style, dynamicSelectedStyle.RegisteredCssClass);
1702 if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
1703 AddCssClass (style, levelSelectedStyles [item.Depth].CssClass);
1704 AddCssClass (style, levelSelectedStyles [item.Depth].RegisteredCssClass);
1708 else {
1709 // styles are not registered
1710 if (!isDynamicItem && staticMenuItemStyle != null) {
1711 style.CopyFrom (staticMenuItemStyle);
1713 if (isDynamicItem && dynamicMenuItemStyle != null) {
1714 style.CopyFrom (dynamicMenuItemStyle);
1716 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
1717 style.CopyFrom (levelMenuItemStyles [item.Depth]);
1719 if (item == SelectedItem) {
1720 if (!isDynamicItem && staticSelectedStyle != null) {
1721 style.CopyFrom (staticSelectedStyle);
1723 if (isDynamicItem && dynamicSelectedStyle != null) {
1724 style.CopyFrom (dynamicSelectedStyle);
1726 if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
1727 style.CopyFrom (levelSelectedStyles [item.Depth]);
1731 style.AddAttributesToRender (writer);
1733 writer.AddAttribute ("id", GetItemClientId (item, "i"));
1735 writer.AddAttribute ("cellpadding", "0", false);
1736 writer.AddAttribute ("cellspacing", "0", false);
1737 writer.AddAttribute ("border", "0", false);
1738 writer.AddAttribute ("width", "100%", false);
1739 writer.RenderBeginTag (HtmlTextWriterTag.Table);
1740 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1742 // Menu item text
1744 if (vertical)
1745 writer.AddStyleAttribute (HtmlTextWriterStyle.Width, "100%");
1746 if (!ItemWrap)
1747 writer.AddStyleAttribute ("white-space", "nowrap");
1748 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1750 RenderItemHref (writer, item);
1752 Style linkStyle = new Style ();
1753 if (Page.Header != null) {
1754 // styles are registered
1755 AddCssClass (linkStyle, ControlLinkStyle.RegisteredCssClass);
1757 if (!isDynamicItem && staticMenuItemStyle != null) {
1758 AddCssClass (linkStyle, staticMenuItemStyle.CssClass);
1759 AddCssClass (linkStyle, staticMenuItemLinkStyle.RegisteredCssClass);
1761 if (isDynamicItem && dynamicMenuItemStyle != null) {
1762 AddCssClass (linkStyle, dynamicMenuItemStyle.CssClass);
1763 AddCssClass (linkStyle, dynamicMenuItemLinkStyle.RegisteredCssClass);
1765 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
1766 AddCssClass (linkStyle, levelMenuItemStyles [item.Depth].CssClass);
1767 AddCssClass (linkStyle, levelMenuItemLinkStyles [item.Depth].RegisteredCssClass);
1769 if (item == SelectedItem) {
1770 if (!isDynamicItem && staticSelectedStyle != null) {
1771 AddCssClass (linkStyle, staticSelectedStyle.CssClass);
1772 AddCssClass (linkStyle, staticSelectedLinkStyle.RegisteredCssClass);
1774 if (isDynamicItem && dynamicSelectedStyle != null) {
1775 AddCssClass (linkStyle, dynamicSelectedStyle.CssClass);
1776 AddCssClass (linkStyle, dynamicSelectedLinkStyle.RegisteredCssClass);
1778 if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
1779 AddCssClass (linkStyle, levelSelectedStyles [item.Depth].CssClass);
1780 AddCssClass (linkStyle, levelSelectedLinkStyles [item.Depth].RegisteredCssClass);
1784 else {
1785 // styles are not registered
1786 linkStyle.CopyFrom (ControlLinkStyle);
1788 if (!isDynamicItem && staticMenuItemStyle != null) {
1789 linkStyle.CopyFrom (staticMenuItemLinkStyle);
1791 if (isDynamicItem && dynamicMenuItemStyle != null) {
1792 linkStyle.CopyFrom (dynamicMenuItemLinkStyle);
1794 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
1795 linkStyle.CopyFrom (levelMenuItemLinkStyles [item.Depth]);
1797 if (item == SelectedItem) {
1798 if (!isDynamicItem && staticSelectedStyle != null) {
1799 linkStyle.CopyFrom (staticSelectedLinkStyle);
1801 if (isDynamicItem && dynamicSelectedStyle != null) {
1802 linkStyle.CopyFrom (dynamicSelectedLinkStyle);
1804 if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
1805 linkStyle.CopyFrom (levelSelectedLinkStyles [item.Depth]);
1809 linkStyle.AlwaysRenderTextDecoration = true;
1811 linkStyle.AddAttributesToRender (writer);
1813 writer.AddAttribute ("id", GetItemClientId (item, "l"));
1815 if (item.Depth > 0 && !isDynamicItem) {
1816 Unit indent = new Unit (StaticSubMenuIndent.Value * item.Depth, StaticSubMenuIndent.Type);
1817 writer.AddStyleAttribute ("margin-left", indent.ToString ());
1819 writer.RenderBeginTag (HtmlTextWriterTag.A);
1820 RenderItemContent (writer, item, isDynamicItem);
1821 writer.RenderEndTag (); // A
1823 writer.RenderEndTag (); // TD
1825 // Popup image
1827 if (dynamicChildren) {
1828 string popOutImage = GetPopOutImage (item, isDynamicItem);
1829 if (popOutImage != null) {
1830 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1831 writer.AddAttribute ("src", ResolveClientUrl (popOutImage));
1832 writer.AddAttribute ("border", "0");
1833 string toolTip = String.Format (isDynamicItem ? DynamicPopOutImageTextFormatString : StaticPopOutImageTextFormatString, item.Text);
1834 writer.AddAttribute (HtmlTextWriterAttribute.Alt, toolTip);
1835 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1836 writer.RenderEndTag (); // IMG
1837 writer.RenderEndTag (); // TD
1841 writer.RenderEndTag (); // TR
1842 writer.RenderEndTag (); // TABLE
1844 writer.RenderEndTag (); // TD
1846 if (!vertical && itemSpacing == Unit.Empty && (notLast || (displayChildren && !dynamicChildren))) {
1847 writer.AddStyleAttribute ("width", "3px");
1848 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1849 writer.RenderEndTag ();
1852 // Bottom separator image
1853 string separatorImg = item.SeparatorImageUrl;
1854 if (separatorImg.Length == 0) {
1855 if (isDynamicItem)
1856 separatorImg = DynamicBottomSeparatorImageUrl;
1857 else
1858 separatorImg = StaticBottomSeparatorImageUrl;
1860 if (separatorImg.Length > 0) {
1861 if (!vertical)
1862 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1863 writer.AddAttribute ("src", ResolveClientUrl (separatorImg));
1864 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1865 writer.RenderEndTag (); // IMG
1866 if (!vertical)
1867 writer.RenderEndTag (); // TD
1870 if (vertical)
1871 writer.RenderEndTag (); // TR
1873 if (itemSpacing != Unit.Empty)
1874 RenderMenuItemSpacing (writer, itemSpacing, vertical);
1876 // Submenu
1878 if (displayChildren && !dynamicChildren) {
1879 if (vertical)
1880 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1881 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1882 writer.AddAttribute ("width", "100%");
1883 RenderMenu (writer, item.ChildItems, Orientation == Orientation.Vertical, false, item.Depth + 1, notLast);
1884 if (item.Depth + 2 == StaticDisplayLevels)
1885 RenderDynamicMenu (writer, item.ChildItems);
1886 writer.RenderEndTag (); // TD
1887 if (vertical)
1888 writer.RenderEndTag (); // TR
1893 void RenderItemContent (HtmlTextWriter writer, MenuItem item, bool isDynamicItem) {
1894 if (_menuItemControls!=null && _menuItemControls [item] != null) {
1895 ((Control) _menuItemControls [item]).Render (writer);
1897 else {
1899 if (!String.IsNullOrEmpty (item.ImageUrl)) {
1900 writer.AddAttribute (HtmlTextWriterAttribute.Src, ResolveClientUrl (item.ImageUrl));
1901 writer.AddAttribute (HtmlTextWriterAttribute.Alt, item.ToolTip);
1902 writer.AddStyleAttribute (HtmlTextWriterStyle.BorderStyle, "none");
1903 writer.AddStyleAttribute (HtmlTextWriterStyle.VerticalAlign, "middle");
1904 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1905 writer.RenderEndTag (); // IMG
1908 if (isDynamicItem && DynamicItemFormatString.Length > 0) {
1909 writer.Write (String.Format (DynamicItemFormatString, item.Text));
1911 else if (!isDynamicItem && StaticItemFormatString.Length > 0) {
1912 writer.Write (String.Format (StaticItemFormatString, item.Text));
1914 else {
1915 writer.Write (item.Text);
1920 Unit GetItemSpacing (MenuItem item, bool dynamic)
1922 Unit itemSpacing = Unit.Empty;
1924 if (item.Selected) {
1925 if (levelSelectedStyles != null && item.Depth < levelSelectedStyles.Count) {
1926 itemSpacing = levelSelectedStyles [item.Depth].ItemSpacing;
1927 if (itemSpacing != Unit.Empty) return itemSpacing;
1930 if (dynamic && dynamicSelectedStyle != null)
1931 itemSpacing = dynamicSelectedStyle.ItemSpacing;
1932 else if (!dynamic && staticSelectedStyle != null)
1933 itemSpacing = staticSelectedStyle.ItemSpacing;
1934 if (itemSpacing != Unit.Empty)
1935 return itemSpacing;
1938 if (levelMenuItemStyles != null && item.Depth < levelMenuItemStyles.Count) {
1939 itemSpacing = levelMenuItemStyles [item.Depth].ItemSpacing;
1940 if (itemSpacing != Unit.Empty) return itemSpacing;
1943 if (dynamic && dynamicMenuItemStyle != null)
1944 return dynamicMenuItemStyle.ItemSpacing;
1945 else if (!dynamic && staticMenuItemStyle != null)
1946 return staticMenuItemStyle.ItemSpacing;
1947 else
1948 return Unit.Empty;
1951 string GetPopOutImage (MenuItem item, bool isDynamicItem)
1953 if (item.PopOutImageUrl != "")
1954 return item.PopOutImageUrl;
1956 if (isDynamicItem) {
1957 if (DynamicPopOutImageUrl != "")
1958 return DynamicPopOutImageUrl;
1959 if (DynamicEnableDefaultPopOutImage)
1960 return Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_plus.gif");
1961 } else {
1962 if (StaticPopOutImageUrl != "")
1963 return StaticPopOutImageUrl;
1964 if (StaticEnableDefaultPopOutImage)
1965 return Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_plus.gif");
1967 return null;
1970 void RenderItemHref (HtmlTextWriter writer, MenuItem item)
1972 if (!item.BranchEnabled) {
1973 writer.AddAttribute ("disabled", "true", false);
1975 else if (!item.Selectable) {
1976 writer.AddAttribute ("href", "#", false);
1977 writer.AddStyleAttribute ("cursor", "text");
1979 else if (item.NavigateUrl != "") {
1980 string target = item.Target != "" ? item.Target : Target;
1981 #if TARGET_J2EE
1982 string navUrl = ResolveClientUrl (item.NavigateUrl, String.Compare (target, "_blank", StringComparison.InvariantCultureIgnoreCase) != 0);
1983 #else
1984 string navUrl = ResolveClientUrl (item.NavigateUrl);
1985 #endif
1986 writer.AddAttribute ("href", navUrl);
1987 if (target != "")
1988 writer.AddAttribute ("target", target);
1990 else {
1991 writer.AddAttribute ("href", GetClientEvent (item));
1996 string GetItemClientId (MenuItem item, string sufix)
1998 return ClientID + "_" + item.Path + sufix;
2001 string GetClientEvent (MenuItem item)
2003 return Page.ClientScript.GetPostBackClientHyperlink (this, item.Path, true);
2006 class MenuTemplateWriter : TextWriter
2008 char [] _buffer;
2009 int _ptr = 0;
2011 public MenuTemplateWriter (char [] buffer)
2013 _buffer = buffer;
2016 public override Encoding Encoding
2018 get { return Encoding.Unicode; }
2021 public override void Write (char value)
2023 if (_ptr == _buffer.Length)
2024 EnsureCapacity ();
2026 _buffer [_ptr++] = value;
2029 public override void Write (string value)
2031 if (value == null)
2032 return;
2034 if (_ptr + value.Length >= _buffer.Length)
2035 EnsureCapacity ();
2037 for (int i = 0; i < value.Length; i++)
2038 _buffer [_ptr++] = value [i];
2041 void EnsureCapacity ()
2043 char [] tmpBuffer = new char [_buffer.Length * 2];
2044 Array.Copy (_buffer, tmpBuffer, _buffer.Length);
2046 _buffer = tmpBuffer;
2050 class MenuRenderHtmlTemplate
2052 public const string Marker = "\u093a\u093b\u0971";
2053 char [] _templateHtml;
2055 MenuTemplateWriter _templateWriter;
2056 ArrayList idxs = new ArrayList (32);
2058 public MenuRenderHtmlTemplate ()
2060 _templateHtml = new char [1024];
2061 _templateWriter = new MenuTemplateWriter (_templateHtml);
2064 public static string GetMarker (int num)
2066 char charNum = (char) ((int) '\u0971' + num);
2067 return string.Concat (Marker, charNum);
2070 public HtmlTextWriter GetMenuTemplateWriter()
2072 return new HtmlTextWriter (_templateWriter);
2075 public void Parse ()
2077 int mpos = 0;
2078 for (int i = 0; i < _templateHtml.Length; i++) {
2079 if (_templateHtml [i] == '\0') {
2080 idxs.Add (i);
2081 break;
2084 if (_templateHtml [i] != Marker [mpos]) {
2085 mpos = 0;
2086 continue;
2089 mpos++;
2090 if (mpos == Marker.Length) {
2091 mpos = 0;
2092 idxs.Add (i - Marker.Length + 1);
2097 public void RenderTemplate (HtmlTextWriter writer, string [] dynamicParts, int start, int count)
2099 if (idxs.Count == 0)
2100 return;
2102 int partStart = 0;
2103 int partEnd = (start == 0) ? -Marker.Length - 1 : (int) idxs [start - 1];
2104 int di = 0;
2106 int i = start;
2107 int total = start + count;
2108 for (; i < total; i++) {
2110 partStart = partEnd + Marker.Length + 1;
2111 partEnd = (int) idxs [i];
2113 // write static part
2114 writer.Write (_templateHtml, partStart, partEnd - partStart);
2116 // write synamic part
2117 di = (int) _templateHtml [partEnd + Marker.Length] - 0x971;
2118 writer.Write (dynamicParts [di]);
2121 partStart = partEnd + Marker.Length + 1;
2122 partEnd = (int) idxs [i];
2124 writer.Write (_templateHtml, partStart, partEnd - partStart);
2131 #endif