2 // System.Web.UI.WebControls.Menu.cs
5 // Lluis Sanchez Gual (lluis@novell.com)
6 // Igor Zelmanovich (igorz@mainsoft.com)
8 // (C) 2004 Novell, Inc (http://www.novell.com)
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:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
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.
35 using System.Collections;
37 using System.ComponentModel;
39 using System.Web.Handlers;
40 using System.Collections.Specialized;
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;
74 Hashtable _menuItemControls;
75 bool _requiresChildControlsDataBinding;
76 SiteMapNode _currSiteMapNode;
77 int registeredStylesCounter = -1;
78 List<Style> levelSelectedLinkStyles;
79 List<Style> levelMenuItemLinkStyles;
81 Style controlLinkStyle;
82 Style dynamicMenuItemLinkStyle;
83 Style staticMenuItemLinkStyle;
84 Style dynamicSelectedLinkStyle;
85 Style staticSelectedLinkStyle;
86 Style dynamicHoverLinkStyle;
87 Style staticHoverLinkStyle;
89 bool includeStyleBlock = true;
90 MenuRenderingMode renderingMode = MenuRenderingMode.Default;
92 static readonly object MenuItemClickEvent = new object();
93 static readonly object MenuItemDataBoundEvent = new object();
95 public static readonly string MenuItemClickCommandName = "Click";
97 public event MenuEventHandler MenuItemClick {
98 add { Events.AddHandler (MenuItemClickEvent, value); }
99 remove { Events.RemoveHandler (MenuItemClickEvent, value); }
102 public event MenuEventHandler MenuItemDataBound {
103 add { Events.AddHandler (MenuItemDataBoundEvent, value); }
104 remove { Events.RemoveHandler (MenuItemDataBoundEvent, value); }
107 protected virtual void OnMenuItemClick (MenuEventArgs e)
109 if (Events != null) {
110 MenuEventHandler eh = (MenuEventHandler) Events [MenuItemClickEvent];
111 if (eh != null) eh (this, e);
115 protected virtual void OnMenuItemDataBound (MenuEventArgs e)
117 if (Events != null) {
118 MenuEventHandler eh = (MenuEventHandler) Events [MenuItemDataBoundEvent];
119 if (eh != null) eh (this, e);
123 [DefaultValue (true)]
124 [Description ("Determines whether or not to render the inline style block (only used in standards compliance mode)")]
125 public bool IncludeStyleBlock {
126 get { return includeStyleBlock; }
127 set { includeStyleBlock = value; }
130 [DefaultValue (MenuRenderingMode.Default)]
131 public MenuRenderingMode RenderingMode {
132 get { return renderingMode; }
134 if (value < MenuRenderingMode.Default || value > MenuRenderingMode.List)
135 throw new ArgumentOutOfRangeException ("value");
137 renderingMode = value;
141 [DefaultValueAttribute (null)]
142 [PersistenceMode (PersistenceMode.InnerProperty)]
143 [EditorAttribute ("System.Web.UI.Design.WebControls.MenuBindingsEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
144 [MergablePropertyAttribute (false)]
145 public MenuItemBindingCollection DataBindings {
147 if (dataBindings == null) {
148 dataBindings = new MenuItemBindingCollection ();
149 if (IsTrackingViewState)
150 ((IStateManager)dataBindings).TrackViewState();
157 [ThemeableAttribute (false)]
158 public int DisappearAfter {
160 object o = ViewState ["DisappearAfter"];
161 if (o != null) return (int)o;
165 ViewState["DisappearAfter"] = value;
169 [ThemeableAttribute (true)]
172 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
173 public string DynamicBottomSeparatorImageUrl {
175 object o = ViewState ["dbsiu"];
176 if (o != null) return (string)o;
180 ViewState["dbsiu"] = value;
184 [DefaultValueAttribute ("")]
185 public string DynamicItemFormatString {
187 object o = ViewState ["DynamicItemFormatString"];
188 if (o != null) return (string)o;
192 ViewState["DynamicItemFormatString"] = value;
198 [WebCategory ("Appearance")]
199 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
200 public string DynamicTopSeparatorImageUrl {
202 object o = ViewState ["dtsiu"];
203 if (o != null) return (string)o;
207 ViewState["dtsiu"] = value;
213 [WebCategory ("Appearance")]
214 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
215 public string StaticBottomSeparatorImageUrl {
217 object o = ViewState ["sbsiu"];
218 if (o != null) return (string)o;
222 ViewState["sbsiu"] = value;
228 [WebCategory ("Appearance")]
229 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
230 public string StaticTopSeparatorImageUrl {
232 object o = ViewState ["stsiu"];
233 if (o != null) return (string)o;
237 ViewState["stsiu"] = value;
241 [DefaultValue (Orientation.Vertical)]
242 public Orientation Orientation {
244 object o = ViewState ["Orientation"];
245 if (o != null) return (Orientation) o;
246 return Orientation.Vertical;
249 ViewState["Orientation"] = value;
254 [ThemeableAttribute (true)]
255 public int StaticDisplayLevels {
257 object o = ViewState ["StaticDisplayLevels"];
258 if (o != null) return (int)o;
262 if (value < 1) throw new ArgumentOutOfRangeException ();
263 ViewState["StaticDisplayLevels"] = value;
267 [DefaultValueAttribute ("")]
268 public string StaticItemFormatString {
270 object o = ViewState ["StaticItemFormatString"];
271 if (o != null) return (string)o;
275 ViewState["StaticItemFormatString"] = value;
279 [DefaultValue (typeof (Unit), "16px")]
280 [ThemeableAttribute (true)]
281 public Unit StaticSubMenuIndent {
283 object o = ViewState ["StaticSubMenuIndent"];
286 // LAMESPEC: on 4.0 it returns Unit.Empty and on 3.5 16px
290 return new Unit (16);
294 ViewState["StaticSubMenuIndent"] = value;
298 [ThemeableAttribute (true)]
300 public int MaximumDynamicDisplayLevels {
302 object o = ViewState ["MaximumDynamicDisplayLevels"];
303 if (o != null) return (int)o;
307 if (value < 0) throw new ArgumentOutOfRangeException ();
308 ViewState["MaximumDynamicDisplayLevels"] = value;
313 public int DynamicVerticalOffset {
315 object o = ViewState ["DynamicVerticalOffset"];
316 if (o != null) return (int)o;
320 ViewState["DynamicVerticalOffset"] = value;
325 public int DynamicHorizontalOffset {
327 object o = ViewState ["DynamicHorizontalOffset"];
328 if (o != null) return (int)o;
332 ViewState["DynamicHorizontalOffset"] = value;
336 [DefaultValue (true)]
337 public bool DynamicEnableDefaultPopOutImage {
339 object o = ViewState ["dedpoi"];
340 if (o != null) return (bool)o;
344 ViewState["dedpoi"] = value;
348 [DefaultValue (true)]
349 public bool StaticEnableDefaultPopOutImage {
351 object o = ViewState ["sedpoi"];
352 if (o != null) return (bool)o;
356 ViewState["sedpoi"] = value;
360 [DefaultValueAttribute (null)]
361 [PersistenceMode (PersistenceMode.InnerProperty)]
362 [Editor ("System.Web.UI.Design.MenuItemCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
363 [MergablePropertyAttribute (false)]
364 public MenuItemCollection Items {
367 items = new MenuItemCollection (this);
368 if (IsTrackingViewState)
369 ((IStateManager)items).TrackViewState();
376 public char PathSeparator {
378 object o = ViewState ["PathSeparator"];
379 if(o != null) return (char)o;
383 ViewState ["PathSeparator"] = value;
387 [DefaultValue (false)]
388 public bool ItemWrap {
390 object o = ViewState ["ItemWrap"];
391 if(o != null) return (bool)o;
395 ViewState ["ItemWrap"] = value;
399 Style PopOutBoxStyle {
401 if (popOutBoxStyle == null) {
402 popOutBoxStyle = new Style ();
403 popOutBoxStyle.BackColor = Color.White;
405 return popOutBoxStyle;
409 Style ControlLinkStyle {
411 if (controlLinkStyle == null) {
412 controlLinkStyle = new Style ();
413 controlLinkStyle.AlwaysRenderTextDecoration = true;
415 return controlLinkStyle;
419 Style DynamicMenuItemLinkStyle {
421 if (dynamicMenuItemLinkStyle == null) {
422 dynamicMenuItemLinkStyle = new Style ();
424 return dynamicMenuItemLinkStyle;
428 Style StaticMenuItemLinkStyle {
430 if (staticMenuItemLinkStyle == null) {
431 staticMenuItemLinkStyle = new Style ();
433 return staticMenuItemLinkStyle;
437 Style DynamicSelectedLinkStyle {
439 if (dynamicSelectedLinkStyle == null) {
440 dynamicSelectedLinkStyle = new Style ();
442 return dynamicSelectedLinkStyle;
446 Style StaticSelectedLinkStyle {
448 if (staticSelectedLinkStyle == null) {
449 staticSelectedLinkStyle = new Style ();
451 return staticSelectedLinkStyle;
455 Style DynamicHoverLinkStyle {
457 if (dynamicHoverLinkStyle == null) {
458 dynamicHoverLinkStyle = new Style ();
460 return dynamicHoverLinkStyle;
464 Style StaticHoverLinkStyle {
466 if (staticHoverLinkStyle == null) {
467 staticHoverLinkStyle = new Style ();
469 return staticHoverLinkStyle;
473 [PersistenceMode (PersistenceMode.InnerProperty)]
474 [NotifyParentProperty (true)]
475 [DefaultValue (null)]
476 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
477 public MenuItemStyle DynamicMenuItemStyle {
479 if (dynamicMenuItemStyle == null) {
480 dynamicMenuItemStyle = new MenuItemStyle ();
481 if (IsTrackingViewState)
482 dynamicMenuItemStyle.TrackViewState();
484 return dynamicMenuItemStyle;
488 [PersistenceMode (PersistenceMode.InnerProperty)]
489 [NotifyParentProperty (true)]
490 [DefaultValue (null)]
491 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
492 public MenuItemStyle DynamicSelectedStyle {
494 if (dynamicSelectedStyle == null) {
495 dynamicSelectedStyle = new MenuItemStyle ();
496 if (IsTrackingViewState)
497 dynamicSelectedStyle.TrackViewState();
499 return dynamicSelectedStyle;
503 [PersistenceMode (PersistenceMode.InnerProperty)]
504 [NotifyParentProperty (true)]
505 [DefaultValue (null)]
506 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
507 public SubMenuStyle DynamicMenuStyle {
509 if (dynamicMenuStyle == null) {
510 dynamicMenuStyle = new SubMenuStyle ();
511 if (IsTrackingViewState)
512 dynamicMenuStyle.TrackViewState();
514 return dynamicMenuStyle;
518 [PersistenceMode (PersistenceMode.InnerProperty)]
519 [NotifyParentProperty (true)]
520 [DefaultValue (null)]
521 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
522 public MenuItemStyle StaticMenuItemStyle {
524 if (staticMenuItemStyle == null) {
525 staticMenuItemStyle = new MenuItemStyle ();
526 if (IsTrackingViewState)
527 staticMenuItemStyle.TrackViewState();
529 return staticMenuItemStyle;
533 [PersistenceMode (PersistenceMode.InnerProperty)]
534 [NotifyParentProperty (true)]
535 [DefaultValue (null)]
536 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
537 public MenuItemStyle StaticSelectedStyle {
539 if (staticSelectedStyle == null) {
540 staticSelectedStyle = new MenuItemStyle ();
541 if (IsTrackingViewState)
542 staticSelectedStyle.TrackViewState();
544 return staticSelectedStyle;
548 [PersistenceMode (PersistenceMode.InnerProperty)]
549 [NotifyParentProperty (true)]
550 [DefaultValue (null)]
551 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
552 public SubMenuStyle StaticMenuStyle {
554 if (staticMenuStyle == null) {
555 staticMenuStyle = new SubMenuStyle ();
556 if (IsTrackingViewState)
557 staticMenuStyle.TrackViewState();
559 return staticMenuStyle;
563 [DefaultValue (null)]
564 [PersistenceMode (PersistenceMode.InnerProperty)]
565 [Editor ("System.Web.UI.Design.WebControls.MenuItemStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
566 public MenuItemStyleCollection LevelMenuItemStyles {
568 if (levelMenuItemStyles == null) {
569 levelMenuItemStyles = new MenuItemStyleCollection ();
570 if (IsTrackingViewState)
571 ((IStateManager)levelMenuItemStyles).TrackViewState();
573 return levelMenuItemStyles;
577 [DefaultValue (null)]
578 [PersistenceMode (PersistenceMode.InnerProperty)]
579 [Editor ("System.Web.UI.Design.WebControls.MenuItemStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
580 public MenuItemStyleCollection LevelSelectedStyles {
582 if (levelSelectedStyles == null) {
583 levelSelectedStyles = new MenuItemStyleCollection ();
584 if (IsTrackingViewState)
585 ((IStateManager)levelSelectedStyles).TrackViewState();
587 return levelSelectedStyles;
591 [DefaultValue (null)]
592 [PersistenceMode (PersistenceMode.InnerProperty)]
593 [Editor ("System.Web.UI.Design.WebControls.SubMenuStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
594 public SubMenuStyleCollection LevelSubMenuStyles {
596 if (levelSubMenuStyles == null) {
597 levelSubMenuStyles = new SubMenuStyleCollection ();
598 if (IsTrackingViewState)
599 ((IStateManager)levelSubMenuStyles).TrackViewState();
601 return levelSubMenuStyles;
605 [PersistenceMode (PersistenceMode.InnerProperty)]
606 [NotifyParentProperty (true)]
607 [DefaultValue (null)]
608 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
609 public Style DynamicHoverStyle {
611 if (dynamicHoverStyle == null) {
612 dynamicHoverStyle = new Style ();
613 if (IsTrackingViewState)
614 dynamicHoverStyle.TrackViewState();
616 return dynamicHoverStyle;
620 [PersistenceMode (PersistenceMode.InnerProperty)]
621 [NotifyParentProperty (true)]
622 [DefaultValue (null)]
623 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
624 public Style StaticHoverStyle {
626 if (staticHoverStyle == null) {
627 staticHoverStyle = new Style ();
628 if (IsTrackingViewState)
629 staticHoverStyle.TrackViewState();
631 return staticHoverStyle;
637 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
638 public string ScrollDownImageUrl {
640 object o = ViewState ["sdiu"];
641 if (o != null) return (string)o;
645 ViewState["sdiu"] = value;
651 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
652 public string ScrollUpImageUrl {
654 object o = ViewState ["suiu"];
655 if (o != null) return (string)o;
659 ViewState["suiu"] = value;
664 public string ScrollDownText {
666 object o = ViewState ["ScrollDownText"];
667 if (o != null) return (string) o;
668 return Locale.GetText ("Scroll down");
671 ViewState["ScrollDownText"] = value;
676 public string ScrollUpText {
678 object o = ViewState ["ScrollUpText"];
679 if (o != null) return (string) o;
680 return Locale.GetText ("Scroll up");
683 ViewState["ScrollUpText"] = value;
687 public string DynamicPopOutImageTextFormatString
691 object o = ViewState ["dpoitf"];
692 if (o != null) return (string) o;
693 return Locale.GetText ("Expand {0}");
697 ViewState ["dpoitf"] = value;
704 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
705 public string DynamicPopOutImageUrl {
707 object o = ViewState ["dpoiu"];
708 if (o != null) return (string)o;
712 ViewState["dpoiu"] = value;
716 public string StaticPopOutImageTextFormatString
720 object o = ViewState ["spoitf"];
721 if (o != null) return (string) o;
722 return Locale.GetText ("Expand {0}");
726 ViewState ["spoitf"] = value;
733 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
734 public string StaticPopOutImageUrl {
736 object o = ViewState ["spoiu"];
737 if (o != null) return (string)o;
741 ViewState["spoiu"] = value;
746 public string Target {
748 object o = ViewState ["Target"];
749 if (o != null) return (string) o;
753 ViewState["Target"] = value;
757 [DefaultValue (null)]
758 [TemplateContainer (typeof(MenuItemTemplateContainer), BindingDirection.OneWay)]
759 [PersistenceMode (PersistenceMode.InnerProperty)]
761 public ITemplate StaticItemTemplate {
762 get { return staticItemTemplate; }
763 set { staticItemTemplate = value; }
766 [DefaultValue (null)]
767 [TemplateContainer (typeof(MenuItemTemplateContainer), BindingDirection.OneWay)]
768 [PersistenceMode (PersistenceMode.InnerProperty)]
770 public ITemplate DynamicItemTemplate {
771 get { return dynamicItemTemplate; }
772 set { dynamicItemTemplate = value; }
776 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
777 public MenuItem SelectedItem {
779 if (selectedItem == null && selectedItemPath != null) {
780 selectedItem = FindItemByPos (selectedItemPath);
789 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
790 public string SelectedValue {
791 get { return selectedItem != null ? selectedItem.Value : ""; }
795 public string SkipLinkText
798 object o = ViewState ["SkipLinkText"];
801 return "Skip Navigation Links";
804 ViewState ["SkipLinkText"] = value;
809 internal void SetSelectedItem (MenuItem item)
811 if (selectedItem == item) return;
813 selectedItemPath = item.Path;
816 public MenuItem FindItem (string valuePath)
818 if (valuePath == null) throw new ArgumentNullException ("valuePath");
819 string[] path = valuePath.Split (PathSeparator);
821 MenuItemCollection col = Items;
822 bool foundBranch = true;
823 while (col.Count > 0 && foundBranch) {
825 foreach (MenuItem item in col) {
826 if (item.Value == path [n]) {
827 if (++n == path.Length) return item;
828 col = item.ChildItems;
837 string GetBindingKey (string dataMember, int depth)
839 return dataMember + " " + depth;
842 internal MenuItemBinding FindBindingForItem (string type, int depth)
844 if (bindings == null) return null;
846 MenuItemBinding bin = (MenuItemBinding) bindings [GetBindingKey (type, depth)];
847 if (bin != null) return bin;
849 bin = (MenuItemBinding) bindings [GetBindingKey (type, -1)];
850 if (bin != null) return bin;
852 bin = (MenuItemBinding) bindings [GetBindingKey ("", depth)];
853 if (bin != null) return bin;
855 bin = (MenuItemBinding) bindings [GetBindingKey ("", -1)];
859 protected internal override void PerformDataBinding ()
861 base.PerformDataBinding ();
863 // Do not attempt to bind data if there is no
865 if (!IsBoundUsingDataSourceID && (DataSource == null)) {
866 EnsureChildControlsDataBound ();
870 InitializeDataBindings ();
872 HierarchicalDataSourceView data = GetData ("");
875 throw new InvalidOperationException ("No view returned by data source control.");
878 IHierarchicalEnumerable e = data.Select ();
879 FillBoundChildrenRecursive (e, Items);
881 CreateChildControlsForItems ();
882 ChildControlsCreated = true;
884 EnsureChildControlsDataBound ();
887 void FillBoundChildrenRecursive (IHierarchicalEnumerable hEnumerable, MenuItemCollection itemCollection)
889 if (hEnumerable == null)
891 foreach (object obj in hEnumerable) {
892 IHierarchyData hdata = hEnumerable.GetHierarchyData (obj);
893 MenuItem item = new MenuItem ();
894 itemCollection.Add (item);
897 SiteMapNode siteMapNode = hdata as SiteMapNode;
898 if (siteMapNode != null) {
899 if (_currSiteMapNode == null)
900 _currSiteMapNode = siteMapNode.Provider.CurrentNode;
901 if (siteMapNode == _currSiteMapNode)
902 item.Selected = true;
905 OnMenuItemDataBound (new MenuEventArgs (item));
907 if (hdata == null || !hdata.HasChildren)
910 IHierarchicalEnumerable e = hdata.GetChildren ();
911 FillBoundChildrenRecursive (e, item.ChildItems);
915 protected void SetItemDataBound (MenuItem node, bool dataBound)
917 node.SetDataBound (dataBound);
920 protected void SetItemDataPath (MenuItem node, string dataPath)
922 node.SetDataPath (dataPath);
925 protected void SetItemDataItem (MenuItem node, object dataItem)
927 node.SetDataItem (dataItem);
930 protected internal virtual void RaisePostBackEvent (string eventArgument)
932 ValidateEvent (UniqueID, eventArgument);
936 EnsureChildControls();
937 MenuItem item = FindItemByPos (eventArgument);
938 if (item == null) return;
939 item.Selected = true;
940 OnMenuItemClick (new MenuEventArgs (item));
943 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
945 RaisePostBackEvent (eventArgument);
948 MenuItem FindItemByPos (string path)
950 string[] indexes = path.Split ('_');
951 MenuItem item = null;
953 foreach (string index in indexes) {
954 int i = int.Parse (index);
956 if (i >= Items.Count) return null;
959 if (i >= item.ChildItems.Count) return null;
960 item = item.ChildItems [i];
966 protected override HtmlTextWriterTag TagKey {
967 get { return HtmlTextWriterTag.Table; }
970 protected override void TrackViewState()
974 base.TrackViewState();
975 if (dataBindings != null) {
976 ((IStateManager)dataBindings).TrackViewState ();
979 ((IStateManager)items).TrackViewState();
981 if (dynamicMenuItemStyle != null)
982 dynamicMenuItemStyle.TrackViewState ();
983 if (dynamicMenuStyle != null)
984 dynamicMenuStyle.TrackViewState ();
985 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > 0)
986 ((IStateManager)levelMenuItemStyles).TrackViewState();
987 if (levelSelectedStyles != null && levelMenuItemStyles.Count > 0)
988 ((IStateManager)levelSelectedStyles).TrackViewState();
989 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0)
990 ((IStateManager)levelSubMenuStyles).TrackViewState();
991 if (dynamicSelectedStyle != null)
992 dynamicSelectedStyle.TrackViewState();
993 if (staticMenuItemStyle != null)
994 staticMenuItemStyle.TrackViewState ();
995 if (staticMenuStyle != null)
996 staticMenuStyle.TrackViewState ();
997 if (staticSelectedStyle != null)
998 staticSelectedStyle.TrackViewState();
999 if (staticHoverStyle != null)
1000 staticHoverStyle.TrackViewState();
1001 if (dynamicHoverStyle != null)
1002 dynamicHoverStyle.TrackViewState();
1005 protected override object SaveViewState()
1007 object[] states = new object [14];
1008 states[0] = base.SaveViewState ();
1009 states[1] = dataBindings == null ? null : ((IStateManager)dataBindings).SaveViewState();
1010 states[2] = items == null ? null : ((IStateManager)items).SaveViewState();
1011 states[3] = dynamicMenuItemStyle == null ? null : dynamicMenuItemStyle.SaveViewState();
1012 states[4] = dynamicMenuStyle == null ? null : dynamicMenuStyle.SaveViewState();
1013 states[5] = levelMenuItemStyles == null ? null : ((IStateManager)levelMenuItemStyles).SaveViewState();
1014 states[6] = levelSelectedStyles == null ? null : ((IStateManager)levelSelectedStyles).SaveViewState();
1015 states[7] = dynamicSelectedStyle == null ? null : dynamicSelectedStyle.SaveViewState();
1016 states[8] = (staticMenuItemStyle == null ? null : staticMenuItemStyle.SaveViewState());
1017 states[9] = staticMenuStyle == null ? null : staticMenuStyle.SaveViewState();
1018 states[10] = staticSelectedStyle == null ? null : staticSelectedStyle.SaveViewState();
1019 states[11] = staticHoverStyle == null ? null : staticHoverStyle.SaveViewState();
1020 states[12] = dynamicHoverStyle == null ? null : dynamicHoverStyle.SaveViewState();
1021 states[13] = levelSubMenuStyles == null ? null : ((IStateManager)levelSubMenuStyles).SaveViewState();
1023 for (int i = states.Length - 1; i >= 0; i--) {
1024 if (states [i] != null)
1031 protected override void LoadViewState (object savedState)
1033 if (savedState == null)
1036 object [] states = (object []) savedState;
1037 base.LoadViewState (states[0]);
1039 if (states[1] != null)
1040 ((IStateManager)DataBindings).LoadViewState(states[1]);
1041 if (states[2] != null)
1042 ((IStateManager)Items).LoadViewState(states[2]);
1043 if (states[3] != null)
1044 DynamicMenuItemStyle.LoadViewState (states[3]);
1045 if (states[4] != null)
1046 DynamicMenuStyle.LoadViewState (states[4]);
1047 if (states[5] != null)
1048 ((IStateManager)LevelMenuItemStyles).LoadViewState(states[5]);
1049 if (states[6] != null)
1050 ((IStateManager)LevelSelectedStyles).LoadViewState(states[6]);
1051 if (states[7] != null)
1052 DynamicSelectedStyle.LoadViewState (states[7]);
1053 if (states[8] != null)
1054 StaticMenuItemStyle.LoadViewState (states[8]);
1055 if (states[9] != null)
1056 StaticMenuStyle.LoadViewState (states[9]);
1057 if (states[10] != null)
1058 StaticSelectedStyle.LoadViewState (states[10]);
1059 if (states[11] != null)
1060 StaticHoverStyle.LoadViewState (states[11]);
1061 if (states[12] != null)
1062 DynamicHoverStyle.LoadViewState (states[12]);
1063 if (states[13] != null)
1064 ((IStateManager)LevelSubMenuStyles).LoadViewState(states[13]);
1067 protected internal override void OnInit (EventArgs e)
1069 Page.RegisterRequiresControlState (this);
1073 protected internal override void LoadControlState (object ob)
1075 if (ob == null) return;
1076 object[] state = (object[]) ob;
1077 base.LoadControlState (state[0]);
1078 selectedItemPath = state[1] as string;
1081 protected internal override object SaveControlState ()
1083 object bstate = base.SaveControlState ();
1084 object mstate = selectedItemPath;
1086 if (bstate != null || mstate != null)
1087 return new object[] { bstate, mstate };
1092 protected internal override void CreateChildControls ()
1094 if (!IsBoundUsingDataSourceID && (DataSource == null)) {
1095 CreateChildControlsForItems ();
1102 void CreateChildControlsForItems () {
1104 // Check for HasChildViewState to avoid unnecessary calls to ClearChildViewState.
1105 if (HasChildViewState)
1106 ClearChildViewState ();
1107 _menuItemControls = new Hashtable ();
1108 CreateChildControlsForItems (Items);
1109 _requiresChildControlsDataBinding = true;
1112 void CreateChildControlsForItems (MenuItemCollection items ) {
1113 foreach (MenuItem item in items) {
1114 bool isDynamicItem = IsDynamicItem (item);
1115 if (isDynamicItem && dynamicItemTemplate != null) {
1116 MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
1117 dynamicItemTemplate.InstantiateIn (cter);
1118 _menuItemControls [item] = cter;
1119 Controls.Add (cter);
1121 else if (!isDynamicItem && staticItemTemplate != null) {
1122 MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
1123 staticItemTemplate.InstantiateIn (cter);
1124 _menuItemControls [item] = cter;
1125 Controls.Add (cter);
1127 if (item.HasChildData)
1128 CreateChildControlsForItems (item.ChildItems);
1132 protected override void EnsureDataBound ()
1134 base.EnsureDataBound ();
1136 EnsureChildControlsDataBound ();
1139 void EnsureChildControlsDataBound () {
1140 if (!_requiresChildControlsDataBinding)
1142 DataBindChildren ();
1143 _requiresChildControlsDataBinding = false;
1146 [MonoTODO ("Not implemented")]
1147 protected override IDictionary GetDesignModeState ()
1149 throw new NotImplementedException ();
1152 [MonoTODO ("Not implemented")]
1153 protected override void SetDesignModeState (IDictionary data)
1155 throw new NotImplementedException ();
1158 public override ControlCollection Controls {
1159 get { return base.Controls; }
1162 public sealed override void DataBind ()
1167 protected override bool OnBubbleEvent (object source, EventArgs args)
1169 if (!(args is CommandEventArgs))
1172 MenuEventArgs menuArgs = args as MenuEventArgs;
1173 if (menuArgs != null && string.Equals (menuArgs.CommandName, MenuItemClickCommandName))
1174 OnMenuItemClick (menuArgs);
1178 protected override void OnDataBinding (EventArgs e)
1180 EnsureChildControls ();
1181 base.OnDataBinding (e);
1184 const string onPreRenderScript = "var {0} = new Object ();\n{0}.webForm = {1};\n{0}.disappearAfter = {2};\n{0}.vertical = {3};";
1186 protected internal override void OnPreRender (EventArgs e)
1188 base.OnPreRender (e);
1190 if (!Page.ClientScript.IsClientScriptIncludeRegistered (typeof(Menu), "Menu.js")) {
1191 string url = Page.ClientScript.GetWebResourceUrl (typeof(Menu), "Menu.js");
1192 Page.ClientScript.RegisterClientScriptInclude (typeof(Menu), "Menu.js", url);
1195 string cmenu = ClientID + "_data";
1196 string script = String.Format (onPreRenderScript,
1198 Page.IsMultiForm ? Page.theForm : "window",
1199 ClientScriptManager.GetScriptLiteral (DisappearAfter),
1200 ClientScriptManager.GetScriptLiteral (Orientation == Orientation.Vertical));
1202 if (DynamicHorizontalOffset != 0)
1203 script += String.Concat (cmenu, ".dho = ", ClientScriptManager.GetScriptLiteral (DynamicHorizontalOffset), ";\n");
1204 if (DynamicVerticalOffset != 0)
1205 script += String.Concat (cmenu, ".dvo = ", ClientScriptManager.GetScriptLiteral (DynamicVerticalOffset), ";\n");
1207 // The order in which styles are defined matters when more than one class
1208 // is assigned to an element
1209 RegisterStyle (PopOutBoxStyle);
1210 RegisterStyle (ControlStyle, ControlLinkStyle);
1212 if (staticMenuItemStyle != null)
1213 RegisterStyle (StaticMenuItemStyle, StaticMenuItemLinkStyle);
1215 if (staticMenuStyle != null)
1216 RegisterStyle (StaticMenuStyle);
1218 if (dynamicMenuItemStyle != null)
1219 RegisterStyle (DynamicMenuItemStyle, DynamicMenuItemLinkStyle);
1221 if (dynamicMenuStyle != null)
1222 RegisterStyle (DynamicMenuStyle);
1224 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > 0) {
1225 levelMenuItemLinkStyles = new List<Style> (levelMenuItemStyles.Count);
1226 foreach (Style style in levelMenuItemStyles) {
1227 Style linkStyle = new Style ();
1228 levelMenuItemLinkStyles.Add (linkStyle);
1229 RegisterStyle (style, linkStyle);
1233 if (levelSubMenuStyles != null)
1234 foreach (Style style in levelSubMenuStyles)
1235 RegisterStyle (style);
1237 if (staticSelectedStyle != null)
1238 RegisterStyle (staticSelectedStyle, StaticSelectedLinkStyle);
1240 if (dynamicSelectedStyle != null)
1241 RegisterStyle (dynamicSelectedStyle, DynamicSelectedLinkStyle);
1243 if (levelSelectedStyles != null && levelSelectedStyles.Count > 0) {
1244 levelSelectedLinkStyles = new List<Style> (levelSelectedStyles.Count);
1245 foreach (Style style in levelSelectedStyles) {
1246 Style linkStyle = new Style ();
1247 levelSelectedLinkStyles.Add (linkStyle);
1248 RegisterStyle (style, linkStyle);
1252 if (staticHoverStyle != null) {
1253 if (Page.Header == null)
1254 throw new InvalidOperationException ("Using Menu.StaticHoverStyle requires Page.Header to be non-null (e.g. <head runat=\"server\" />).");
1255 RegisterStyle (staticHoverStyle, StaticHoverLinkStyle);
1256 script += string.Concat (cmenu, ".staticHover = ", ClientScriptManager.GetScriptLiteral (staticHoverStyle.RegisteredCssClass), ";\n");
1257 script += string.Concat (cmenu, ".staticLinkHover = ", ClientScriptManager.GetScriptLiteral (StaticHoverLinkStyle.RegisteredCssClass), ";\n");
1260 if (dynamicHoverStyle != null) {
1261 if (Page.Header == null)
1262 throw new InvalidOperationException ("Using Menu.DynamicHoverStyle requires Page.Header to be non-null (e.g. <head runat=\"server\" />).");
1263 RegisterStyle (dynamicHoverStyle, DynamicHoverLinkStyle);
1264 script += string.Concat (cmenu, ".dynamicHover = ", ClientScriptManager.GetScriptLiteral (dynamicHoverStyle.RegisteredCssClass), ";\n");
1265 script += string.Concat (cmenu, ".dynamicLinkHover = ", ClientScriptManager.GetScriptLiteral (DynamicHoverLinkStyle.RegisteredCssClass), ";\n");
1268 Page.ClientScript.RegisterWebFormClientScript ();
1269 Page.ClientScript.RegisterStartupScript (typeof(Menu), ClientID, script, true);
1273 void InitializeDataBindings () {
1274 if (dataBindings != null && dataBindings.Count > 0) {
1275 bindings = new Hashtable ();
1276 foreach (MenuItemBinding bin in dataBindings) {
1277 string key = GetBindingKey (bin.DataMember, bin.Depth);
1278 bindings [key] = bin;
1285 string IncrementStyleClassName () {
1286 registeredStylesCounter++;
1287 return ClientID + "_" + registeredStylesCounter;
1290 void RegisterStyle (Style baseStyle, Style linkStyle) {
1291 linkStyle.CopyTextStylesFrom (baseStyle);
1292 linkStyle.BorderStyle = BorderStyle.None;
1293 RegisterStyle (linkStyle);
1294 RegisterStyle (baseStyle);
1297 void RegisterStyle (Style baseStyle)
1299 if (Page.Header == null)
1301 string className = IncrementStyleClassName ();
1302 baseStyle.SetRegisteredCssClass (className);
1303 Page.Header.StyleSheet.CreateStyleRule (baseStyle, this, "." + className);
1306 protected internal override void Render (HtmlTextWriter writer)
1308 if (Items.Count > 0)
1309 base.Render (writer);
1312 protected override void AddAttributesToRender (HtmlTextWriter writer)
1314 writer.AddAttribute ("cellpadding", "0", false);
1315 writer.AddAttribute ("cellspacing", "0", false);
1316 writer.AddAttribute ("border", "0", false);
1317 if (Page.Header != null) {
1318 // styles are registered
1319 if (staticMenuStyle != null) {
1320 AddCssClass (ControlStyle, staticMenuStyle.CssClass);
1321 AddCssClass (ControlStyle, staticMenuStyle.RegisteredCssClass);
1323 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0) {
1324 AddCssClass (ControlStyle, levelSubMenuStyles [0].CssClass);
1325 AddCssClass (ControlStyle, levelSubMenuStyles [0].RegisteredCssClass);
1329 // styles are not registered
1330 if (staticMenuStyle != null){
1331 ControlStyle.CopyFrom (staticMenuStyle);
1333 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0) {
1334 ControlStyle.CopyFrom (levelSubMenuStyles [0]);
1337 base.AddAttributesToRender (writer);
1340 void AddCssClass (Style style, string cssClass) {
1341 style.AddCssClass (cssClass);
1344 public override void RenderBeginTag (HtmlTextWriter writer)
1346 string skipLinkText = SkipLinkText;
1347 if (!String.IsNullOrEmpty (skipLinkText)) {
1348 // <a href="#ID_SkipLink">
1349 writer.AddAttribute (HtmlTextWriterAttribute.Href, "#" + ClientID + "_SkipLink");
1350 writer.RenderBeginTag (HtmlTextWriterTag.A);
1352 // <img alt="" height="0" width="0" src="" style="border-width:0px;"/>
1353 writer.AddAttribute (HtmlTextWriterAttribute.Alt, skipLinkText);
1354 writer.AddAttribute (HtmlTextWriterAttribute.Height, "0");
1355 writer.AddAttribute (HtmlTextWriterAttribute.Width, "0");
1358 ClientScriptManager csm;
1361 csm = page.ClientScript;
1363 csm = new ClientScriptManager (null);
1364 writer.AddAttribute (HtmlTextWriterAttribute.Src, csm.GetWebResourceUrl (typeof (SiteMapPath), "transparent.gif"));
1365 writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0px");
1366 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1367 writer.RenderEndTag ();
1369 writer.RenderEndTag (); // </a>
1371 base.RenderBeginTag (writer);
1374 public override void RenderEndTag (HtmlTextWriter writer)
1376 base.RenderEndTag (writer);
1378 if (StaticDisplayLevels == 1 && MaximumDynamicDisplayLevels > 0)
1379 RenderDynamicMenu (writer, Items);
1381 string skipLinkText = SkipLinkText;
1382 if (!String.IsNullOrEmpty (skipLinkText)) {
1383 writer.AddAttribute (HtmlTextWriterAttribute.Id, "SkipLink");
1384 writer.RenderBeginTag (HtmlTextWriterTag.A);
1385 writer.RenderEndTag ();
1389 protected internal override void RenderContents (HtmlTextWriter writer)
1391 RenderMenuBody (writer, Items, Orientation == Orientation.Vertical, false, false);
1394 void RenderDynamicMenu (HtmlTextWriter writer, MenuItemCollection items) {
1395 for (int n = 0; n < items.Count; n++) {
1396 if (DisplayChildren (items [n])) {
1397 RenderDynamicMenu (writer, items [n]);
1398 RenderDynamicMenu (writer, items [n].ChildItems);
1403 MenuRenderHtmlTemplate _dynamicTemplate;
1404 MenuRenderHtmlTemplate GetDynamicMenuTemplate (MenuItem item)
1406 if (_dynamicTemplate != null)
1407 return _dynamicTemplate;
1409 _dynamicTemplate = new MenuRenderHtmlTemplate ();
1410 HtmlTextWriter writer = _dynamicTemplate.GetMenuTemplateWriter ();
1412 if (Page.Header != null) {
1413 writer.AddAttribute (HtmlTextWriterAttribute.Class, MenuRenderHtmlTemplate.GetMarker (0));
1416 writer.AddAttribute (HtmlTextWriterAttribute.Style, MenuRenderHtmlTemplate.GetMarker (0));
1419 writer.AddStyleAttribute ("visibility", "hidden");
1420 writer.AddStyleAttribute ("position", "absolute");
1421 writer.AddStyleAttribute ("z-index", "1");
1422 writer.AddStyleAttribute ("left", "0px");
1423 writer.AddStyleAttribute ("top", "0px");
1424 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (1));
1425 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1428 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (2));
1429 writer.AddStyleAttribute ("display", "block");
1430 writer.AddStyleAttribute ("text-align", "center");
1431 writer.AddAttribute ("onmouseover", string.Concat ("Menu_OverScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (3), "','u')"));
1432 writer.AddAttribute ("onmouseout", string.Concat ("Menu_OutScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (4), "','u')"));
1433 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1435 writer.AddAttribute ("src", MenuRenderHtmlTemplate.GetMarker (5)); //src
1436 writer.AddAttribute ("alt", MenuRenderHtmlTemplate.GetMarker (6)); //ScrollUpText
1437 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1438 writer.RenderEndTag (); // IMG
1440 writer.RenderEndTag (); // DIV scroll button
1442 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (7));
1443 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1444 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (8));
1445 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1447 // call of RenderMenu
1448 writer.Write (MenuRenderHtmlTemplate.GetMarker (9));
1450 writer.RenderEndTag (); // DIV Content
1451 writer.RenderEndTag (); // DIV Scroll container
1454 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (0));
1455 writer.AddStyleAttribute ("display", "block");
1456 writer.AddStyleAttribute ("text-align", "center");
1457 writer.AddAttribute ("onmouseover", string.Concat ("Menu_OverScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (1), "','d')"));
1458 writer.AddAttribute ("onmouseout", string.Concat ("Menu_OutScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (2), "','d')"));
1459 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1461 writer.AddAttribute ("src", MenuRenderHtmlTemplate.GetMarker (3)); //src
1462 writer.AddAttribute ("alt", MenuRenderHtmlTemplate.GetMarker (4)); //ScrollDownText
1463 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1464 writer.RenderEndTag (); // IMG
1466 writer.RenderEndTag (); // DIV scroll button
1468 writer.RenderEndTag (); // DIV menu
1470 _dynamicTemplate.Parse ();
1471 return _dynamicTemplate;
1474 void RenderDynamicMenu (HtmlTextWriter writer, MenuItem item)
1476 _dynamicTemplate = GetDynamicMenuTemplate (item);
1478 string idPrefix = ClientID + "_" + item.Path;
1479 string [] param = new string [9];
1480 param [0] = GetCssMenuStyle (true, item.Depth + 1);
1481 param [1] = idPrefix + "s";
1482 param [2] = idPrefix + "cu";
1483 param [3] = item.Path;
1484 param [4] = item.Path;
1485 param [5] = ScrollUpImageUrl != "" ? ScrollUpImageUrl : Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_up.gif");
1486 param [6] = ScrollUpText;
1487 param [7] = idPrefix + "cb";
1488 param [8] = idPrefix + "cc";
1490 _dynamicTemplate.RenderTemplate (writer, param, 0, param.Length);
1492 RenderMenu (writer, item.ChildItems, true, true, item.Depth + 1, false);
1494 string [] param2 = new string [5];
1495 param2 [0] = idPrefix + "cd";
1496 param2 [1] = item.Path;
1497 param2 [2] = item.Path;
1498 param2 [3] = ScrollDownImageUrl != "" ? ScrollDownImageUrl : Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_down.gif");
1499 param2 [4] = ScrollDownText;
1501 _dynamicTemplate.RenderTemplate (writer, param2, param.Length + 1, param2.Length);
1505 string GetCssMenuStyle (bool dynamic, int menuLevel)
1507 if (Page.Header != null) {
1508 // styles are registered
1509 StringBuilder sb = new StringBuilder ();
1511 if (!dynamic && staticMenuStyle != null) {
1512 sb.Append (staticMenuStyle.CssClass);
1514 sb.Append (staticMenuStyle.RegisteredCssClass);
1516 if (dynamic && dynamicMenuStyle != null) {
1517 sb.Append (PopOutBoxStyle.RegisteredCssClass);
1519 sb.Append (dynamicMenuStyle.CssClass);
1521 sb.Append (dynamicMenuStyle.RegisteredCssClass);
1523 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
1524 sb.Append (levelSubMenuStyles [menuLevel].CssClass);
1526 sb.Append (levelSubMenuStyles [menuLevel].RegisteredCssClass);
1528 return sb.ToString ();
1531 // styles are not registered
1532 SubMenuStyle style = new SubMenuStyle ();
1534 if (!dynamic && staticMenuStyle != null) {
1535 style.CopyFrom (staticMenuStyle);
1537 if (dynamic && dynamicMenuStyle != null) {
1538 style.CopyFrom (PopOutBoxStyle);
1539 style.CopyFrom (dynamicMenuStyle);
1541 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
1542 style.CopyFrom (levelSubMenuStyles [menuLevel]);
1544 return style.GetStyleAttributes (null).Value;
1548 void RenderMenuBeginTagAttributes (HtmlTextWriter writer, bool dynamic, int menuLevel) {
1549 writer.AddAttribute ("cellpadding", "0", false);
1550 writer.AddAttribute ("cellspacing", "0", false);
1551 writer.AddAttribute ("border", "0", false);
1554 SubMenuStyle style = new SubMenuStyle ();
1555 FillMenuStyle (dynamic, menuLevel, style);
1556 style.AddAttributesToRender (writer);
1560 void FillMenuStyle (bool dynamic, int menuLevel, SubMenuStyle style) {
1561 if (Page.Header != null) {
1562 // styles are registered
1563 if (!dynamic && staticMenuStyle != null) {
1564 AddCssClass (style, staticMenuStyle.CssClass);
1565 AddCssClass (style, staticMenuStyle.RegisteredCssClass);
1567 if (dynamic && dynamicMenuStyle != null) {
1568 AddCssClass (style, dynamicMenuStyle.CssClass);
1569 AddCssClass (style, dynamicMenuStyle.RegisteredCssClass);
1571 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
1572 AddCssClass (style, levelSubMenuStyles [menuLevel].CssClass);
1573 AddCssClass (style, levelSubMenuStyles [menuLevel].RegisteredCssClass);
1577 // styles are not registered
1578 if (!dynamic && staticMenuStyle != null) {
1579 style.CopyFrom (staticMenuStyle);
1581 if (dynamic && dynamicMenuStyle != null) {
1582 style.CopyFrom (dynamicMenuStyle);
1584 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
1585 style.CopyFrom (levelSubMenuStyles [menuLevel]);
1590 void RenderMenu (HtmlTextWriter writer, MenuItemCollection items, bool vertical, bool dynamic, int menuLevel, bool notLast)
1592 RenderMenuBeginTag (writer, dynamic, menuLevel);
1593 RenderMenuBody (writer, items, vertical, dynamic, notLast);
1594 RenderMenuEndTag (writer);
1597 void RenderMenuBeginTag (HtmlTextWriter writer, bool dynamic, int menuLevel)
1599 RenderMenuBeginTagAttributes (writer, dynamic, menuLevel);
1600 writer.RenderBeginTag (HtmlTextWriterTag.Table);
1603 void RenderMenuEndTag (HtmlTextWriter writer)
1605 writer.RenderEndTag ();
1608 void RenderMenuBody (HtmlTextWriter writer, MenuItemCollection items, bool vertical, bool dynamic, bool notLast) {
1610 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1612 int count = items.Count;
1613 for (int n = 0; n < count; n++) {
1614 MenuItem item = items [n];
1615 Adapters.MenuAdapter adapter = Adapter as Adapters.MenuAdapter;
1616 if (adapter != null)
1617 adapter.RenderItem (writer, item, n);
1619 RenderMenuItem (writer, item, (n + 1 == count) ? notLast : true, n == 0);
1623 writer.RenderEndTag (); // TR
1626 void RenderMenuItemSpacing (HtmlTextWriter writer, Unit itemSpacing, bool vertical) {
1628 writer.AddStyleAttribute ("height", itemSpacing.ToString ());
1629 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1630 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1631 writer.RenderEndTag ();
1632 writer.RenderEndTag ();
1635 writer.AddStyleAttribute ("width", itemSpacing.ToString ());
1636 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1637 writer.RenderEndTag ();
1641 bool IsDynamicItem (MenuItem item) {
1642 return item.Depth + 1 > StaticDisplayLevels;
1645 bool DisplayChildren (MenuItem item) {
1646 return (item.Depth + 1 < StaticDisplayLevels + MaximumDynamicDisplayLevels) && item.ChildItems.Count > 0;
1649 internal void RenderItem (HtmlTextWriter writer, MenuItem item, int position) {
1650 // notLast should be true if item or any of its ancestors is not a
1652 bool notLast = false;
1654 MenuItem child = item;
1655 while (null != (parent = child.Parent)) {
1656 if (child.Index != parent.ChildItems.Count - 1) {
1663 RenderMenuItem (writer, item, notLast, position == 0);
1666 void RenderMenuItem (HtmlTextWriter writer, MenuItem item, bool notLast, bool isFirst) {
1667 bool displayChildren = DisplayChildren (item);
1668 bool dynamicChildren = displayChildren && (item.Depth + 1 >= StaticDisplayLevels);
1669 bool isDynamicItem = IsDynamicItem (item);
1670 bool vertical = (Orientation == Orientation.Vertical) || isDynamicItem;
1672 Unit itemSpacing = GetItemSpacing (item, isDynamicItem);
1674 if (itemSpacing != Unit.Empty && (item.Depth > 0 || !isFirst))
1675 RenderMenuItemSpacing (writer, itemSpacing, vertical);
1677 if(!String.IsNullOrEmpty(item.ToolTip))
1678 writer.AddAttribute (HtmlTextWriterAttribute.Title, item.ToolTip);
1680 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1682 string parentId = isDynamicItem ? "'" + item.Parent.Path + "'" : "null";
1683 if (dynamicChildren) {
1684 writer.AddAttribute ("onmouseover",
1685 "javascript:Menu_OverItem ('" + ClientID + "','" + item.Path + "'," + parentId + ")");
1686 writer.AddAttribute ("onmouseout",
1687 "javascript:Menu_OutItem ('" + ClientID + "','" + item.Path + "')");
1688 } else if (isDynamicItem) {
1689 writer.AddAttribute ("onmouseover",
1690 "javascript:Menu_OverDynamicLeafItem ('" + ClientID + "','" + item.Path + "'," + parentId + ")");
1691 writer.AddAttribute ("onmouseout",
1692 "javascript:Menu_OutItem ('" + ClientID + "','" + item.Path + "'," + parentId + ")");
1694 writer.AddAttribute ("onmouseover",
1695 "javascript:Menu_OverStaticLeafItem ('" + ClientID + "','" + item.Path + "')");
1696 writer.AddAttribute ("onmouseout",
1697 "javascript:Menu_OutItem ('" + ClientID + "','" + item.Path + "')");
1700 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1702 // Top separator image
1704 if (isDynamicItem && DynamicTopSeparatorImageUrl != "") {
1705 writer.AddAttribute ("src", ResolveClientUrl (DynamicTopSeparatorImageUrl));
1706 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1707 writer.RenderEndTag (); // IMG
1709 else if (!isDynamicItem && StaticTopSeparatorImageUrl != "") {
1710 writer.AddAttribute ("src", ResolveClientUrl (StaticTopSeparatorImageUrl));
1711 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1712 writer.RenderEndTag (); // IMG
1717 MenuItemStyle style = new MenuItemStyle ();
1718 if (Page.Header != null) {
1719 // styles are registered
1720 if (!isDynamicItem && staticMenuItemStyle != null) {
1721 AddCssClass (style, staticMenuItemStyle.CssClass);
1722 AddCssClass (style, staticMenuItemStyle.RegisteredCssClass);
1724 if (isDynamicItem && dynamicMenuItemStyle != null) {
1725 AddCssClass (style, dynamicMenuItemStyle.CssClass);
1726 AddCssClass (style, dynamicMenuItemStyle.RegisteredCssClass);
1728 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
1729 AddCssClass (style, levelMenuItemStyles [item.Depth].CssClass);
1730 AddCssClass (style, levelMenuItemStyles [item.Depth].RegisteredCssClass);
1732 if (item == SelectedItem) {
1733 if (!isDynamicItem && staticSelectedStyle != null) {
1734 AddCssClass (style, staticSelectedStyle.CssClass);
1735 AddCssClass (style, staticSelectedStyle.RegisteredCssClass);
1737 if (isDynamicItem && dynamicSelectedStyle != null) {
1738 AddCssClass (style, dynamicSelectedStyle.CssClass);
1739 AddCssClass (style, dynamicSelectedStyle.RegisteredCssClass);
1741 if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
1742 AddCssClass (style, levelSelectedStyles [item.Depth].CssClass);
1743 AddCssClass (style, levelSelectedStyles [item.Depth].RegisteredCssClass);
1748 // styles are not registered
1749 if (!isDynamicItem && staticMenuItemStyle != null) {
1750 style.CopyFrom (staticMenuItemStyle);
1752 if (isDynamicItem && dynamicMenuItemStyle != null) {
1753 style.CopyFrom (dynamicMenuItemStyle);
1755 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
1756 style.CopyFrom (levelMenuItemStyles [item.Depth]);
1758 if (item == SelectedItem) {
1759 if (!isDynamicItem && staticSelectedStyle != null) {
1760 style.CopyFrom (staticSelectedStyle);
1762 if (isDynamicItem && dynamicSelectedStyle != null) {
1763 style.CopyFrom (dynamicSelectedStyle);
1765 if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
1766 style.CopyFrom (levelSelectedStyles [item.Depth]);
1770 style.AddAttributesToRender (writer);
1772 writer.AddAttribute ("id", GetItemClientId (item, "i"));
1774 writer.AddAttribute ("cellpadding", "0", false);
1775 writer.AddAttribute ("cellspacing", "0", false);
1776 writer.AddAttribute ("border", "0", false);
1777 writer.AddAttribute ("width", "100%", false);
1778 writer.RenderBeginTag (HtmlTextWriterTag.Table);
1779 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1784 writer.AddStyleAttribute (HtmlTextWriterStyle.Width, "100%");
1786 writer.AddStyleAttribute ("white-space", "nowrap");
1787 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1789 RenderItemHref (writer, item);
1791 Style linkStyle = new Style ();
1792 if (Page.Header != null) {
1793 // styles are registered
1794 AddCssClass (linkStyle, ControlLinkStyle.RegisteredCssClass);
1796 if (!isDynamicItem && staticMenuItemStyle != null) {
1797 AddCssClass (linkStyle, staticMenuItemStyle.CssClass);
1798 AddCssClass (linkStyle, staticMenuItemLinkStyle.RegisteredCssClass);
1800 if (isDynamicItem && dynamicMenuItemStyle != null) {
1801 AddCssClass (linkStyle, dynamicMenuItemStyle.CssClass);
1802 AddCssClass (linkStyle, dynamicMenuItemLinkStyle.RegisteredCssClass);
1804 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
1805 AddCssClass (linkStyle, levelMenuItemStyles [item.Depth].CssClass);
1806 AddCssClass (linkStyle, levelMenuItemLinkStyles [item.Depth].RegisteredCssClass);
1808 if (item == SelectedItem) {
1809 if (!isDynamicItem && staticSelectedStyle != null) {
1810 AddCssClass (linkStyle, staticSelectedStyle.CssClass);
1811 AddCssClass (linkStyle, staticSelectedLinkStyle.RegisteredCssClass);
1813 if (isDynamicItem && dynamicSelectedStyle != null) {
1814 AddCssClass (linkStyle, dynamicSelectedStyle.CssClass);
1815 AddCssClass (linkStyle, dynamicSelectedLinkStyle.RegisteredCssClass);
1817 if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
1818 AddCssClass (linkStyle, levelSelectedStyles [item.Depth].CssClass);
1819 AddCssClass (linkStyle, levelSelectedLinkStyles [item.Depth].RegisteredCssClass);
1824 // styles are not registered
1825 linkStyle.CopyFrom (ControlLinkStyle);
1827 if (!isDynamicItem && staticMenuItemStyle != null) {
1828 linkStyle.CopyFrom (staticMenuItemLinkStyle);
1830 if (isDynamicItem && dynamicMenuItemStyle != null) {
1831 linkStyle.CopyFrom (dynamicMenuItemLinkStyle);
1833 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
1834 linkStyle.CopyFrom (levelMenuItemLinkStyles [item.Depth]);
1836 if (item == SelectedItem) {
1837 if (!isDynamicItem && staticSelectedStyle != null) {
1838 linkStyle.CopyFrom (staticSelectedLinkStyle);
1840 if (isDynamicItem && dynamicSelectedStyle != null) {
1841 linkStyle.CopyFrom (dynamicSelectedLinkStyle);
1843 if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
1844 linkStyle.CopyFrom (levelSelectedLinkStyles [item.Depth]);
1848 linkStyle.AlwaysRenderTextDecoration = true;
1850 linkStyle.AddAttributesToRender (writer);
1852 writer.AddAttribute ("id", GetItemClientId (item, "l"));
1854 if (item.Depth > 0 && !isDynamicItem) {
1857 Unit unit = StaticSubMenuIndent;
1858 if (unit == Unit.Empty)
1863 value = StaticSubMenuIndent.Value;
1865 Unit indent = new Unit (value * item.Depth, StaticSubMenuIndent.Type);
1866 writer.AddStyleAttribute (HtmlTextWriterStyle.MarginLeft, indent.ToString ());
1868 writer.RenderBeginTag (HtmlTextWriterTag.A);
1869 RenderItemContent (writer, item, isDynamicItem);
1870 writer.RenderEndTag (); // A
1872 writer.RenderEndTag (); // TD
1876 if (dynamicChildren) {
1877 string popOutImage = GetPopOutImage (item, isDynamicItem);
1878 if (popOutImage != null) {
1879 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1880 writer.AddAttribute ("src", ResolveClientUrl (popOutImage));
1881 writer.AddAttribute ("border", "0");
1882 string toolTip = String.Format (isDynamicItem ? DynamicPopOutImageTextFormatString : StaticPopOutImageTextFormatString, item.Text);
1883 writer.AddAttribute (HtmlTextWriterAttribute.Alt, toolTip);
1884 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1885 writer.RenderEndTag (); // IMG
1886 writer.RenderEndTag (); // TD
1890 writer.RenderEndTag (); // TR
1891 writer.RenderEndTag (); // TABLE
1893 writer.RenderEndTag (); // TD
1895 if (!vertical && itemSpacing == Unit.Empty && (notLast || (displayChildren && !dynamicChildren))) {
1896 writer.AddStyleAttribute ("width", "3px");
1897 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1898 writer.RenderEndTag ();
1901 // Bottom separator image
1902 string separatorImg = item.SeparatorImageUrl;
1903 if (separatorImg.Length == 0) {
1905 separatorImg = DynamicBottomSeparatorImageUrl;
1907 separatorImg = StaticBottomSeparatorImageUrl;
1909 if (separatorImg.Length > 0) {
1911 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1912 writer.AddAttribute ("src", ResolveClientUrl (separatorImg));
1913 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1914 writer.RenderEndTag (); // IMG
1916 writer.RenderEndTag (); // TD
1920 writer.RenderEndTag (); // TR
1922 if (itemSpacing != Unit.Empty)
1923 RenderMenuItemSpacing (writer, itemSpacing, vertical);
1927 if (displayChildren && !dynamicChildren) {
1929 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
1930 writer.RenderBeginTag (HtmlTextWriterTag.Td);
1931 writer.AddAttribute ("width", "100%");
1932 RenderMenu (writer, item.ChildItems, Orientation == Orientation.Vertical, false, item.Depth + 1, notLast);
1933 if (item.Depth + 2 == StaticDisplayLevels)
1934 RenderDynamicMenu (writer, item.ChildItems);
1935 writer.RenderEndTag (); // TD
1937 writer.RenderEndTag (); // TR
1942 void RenderItemContent (HtmlTextWriter writer, MenuItem item, bool isDynamicItem) {
1943 if (_menuItemControls!=null && _menuItemControls [item] != null) {
1944 ((Control) _menuItemControls [item]).Render (writer);
1948 if (!String.IsNullOrEmpty (item.ImageUrl)) {
1949 writer.AddAttribute (HtmlTextWriterAttribute.Src, ResolveClientUrl (item.ImageUrl));
1950 writer.AddAttribute (HtmlTextWriterAttribute.Alt, item.ToolTip);
1951 writer.AddStyleAttribute (HtmlTextWriterStyle.BorderStyle, "none");
1952 writer.AddStyleAttribute (HtmlTextWriterStyle.VerticalAlign, "middle");
1953 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1954 writer.RenderEndTag (); // IMG
1957 if (isDynamicItem && DynamicItemFormatString.Length > 0) {
1958 writer.Write (String.Format (DynamicItemFormatString, item.Text));
1960 else if (!isDynamicItem && StaticItemFormatString.Length > 0) {
1961 writer.Write (String.Format (StaticItemFormatString, item.Text));
1964 writer.Write (item.Text);
1969 Unit GetItemSpacing (MenuItem item, bool dynamic)
1971 Unit itemSpacing = Unit.Empty;
1973 if (item.Selected) {
1974 if (levelSelectedStyles != null && item.Depth < levelSelectedStyles.Count) {
1975 itemSpacing = levelSelectedStyles [item.Depth].ItemSpacing;
1976 if (itemSpacing != Unit.Empty) return itemSpacing;
1979 if (dynamic && dynamicSelectedStyle != null)
1980 itemSpacing = dynamicSelectedStyle.ItemSpacing;
1981 else if (!dynamic && staticSelectedStyle != null)
1982 itemSpacing = staticSelectedStyle.ItemSpacing;
1983 if (itemSpacing != Unit.Empty)
1987 if (levelMenuItemStyles != null && item.Depth < levelMenuItemStyles.Count) {
1988 itemSpacing = levelMenuItemStyles [item.Depth].ItemSpacing;
1989 if (itemSpacing != Unit.Empty) return itemSpacing;
1992 if (dynamic && dynamicMenuItemStyle != null)
1993 return dynamicMenuItemStyle.ItemSpacing;
1994 else if (!dynamic && staticMenuItemStyle != null)
1995 return staticMenuItemStyle.ItemSpacing;
2000 string GetPopOutImage (MenuItem item, bool isDynamicItem)
2002 if (item.PopOutImageUrl != "")
2003 return item.PopOutImageUrl;
2005 if (isDynamicItem) {
2006 if (DynamicPopOutImageUrl != "")
2007 return DynamicPopOutImageUrl;
2008 if (DynamicEnableDefaultPopOutImage)
2009 return Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_plus.gif");
2011 if (StaticPopOutImageUrl != "")
2012 return StaticPopOutImageUrl;
2013 if (StaticEnableDefaultPopOutImage)
2014 return Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_plus.gif");
2019 void RenderItemHref (HtmlTextWriter writer, MenuItem item)
2021 if (!item.BranchEnabled) {
2022 writer.AddAttribute ("disabled", "true", false);
2024 else if (!item.Selectable) {
2025 writer.AddAttribute ("href", "#", false);
2026 writer.AddStyleAttribute ("cursor", "text");
2028 else if (item.NavigateUrl != "") {
2029 string target = item.Target != "" ? item.Target : Target;
2031 string navUrl = ResolveClientUrl (item.NavigateUrl, String.Compare (target, "_blank", StringComparison.InvariantCultureIgnoreCase) != 0);
2033 string navUrl = ResolveClientUrl (item.NavigateUrl);
2035 writer.AddAttribute ("href", navUrl);
2037 writer.AddAttribute ("target", target);
2040 writer.AddAttribute ("href", GetClientEvent (item));
2045 string GetItemClientId (MenuItem item, string sufix)
2047 return ClientID + "_" + item.Path + sufix;
2050 string GetClientEvent (MenuItem item)
2052 return Page.ClientScript.GetPostBackClientHyperlink (this, item.Path, true);
2055 class MenuTemplateWriter : TextWriter
2060 public MenuTemplateWriter (char [] buffer)
2065 public override Encoding Encoding
2067 get { return Encoding.Unicode; }
2070 public override void Write (char value)
2072 if (_ptr == _buffer.Length)
2075 _buffer [_ptr++] = value;
2078 public override void Write (string value)
2083 if (_ptr + value.Length >= _buffer.Length)
2086 for (int i = 0; i < value.Length; i++)
2087 _buffer [_ptr++] = value [i];
2090 void EnsureCapacity ()
2092 char [] tmpBuffer = new char [_buffer.Length * 2];
2093 Array.Copy (_buffer, tmpBuffer, _buffer.Length);
2095 _buffer = tmpBuffer;
2099 class MenuRenderHtmlTemplate
2101 public const string Marker = "\u093a\u093b\u0971";
2102 char [] _templateHtml;
2104 MenuTemplateWriter _templateWriter;
2105 ArrayList idxs = new ArrayList (32);
2107 public MenuRenderHtmlTemplate ()
2109 _templateHtml = new char [1024];
2110 _templateWriter = new MenuTemplateWriter (_templateHtml);
2113 public static string GetMarker (int num)
2115 char charNum = (char) ((int) '\u0971' + num);
2116 return string.Concat (Marker, charNum);
2119 public HtmlTextWriter GetMenuTemplateWriter()
2121 return new HtmlTextWriter (_templateWriter);
2124 public void Parse ()
2127 for (int i = 0; i < _templateHtml.Length; i++) {
2128 if (_templateHtml [i] == '\0') {
2133 if (_templateHtml [i] != Marker [mpos]) {
2139 if (mpos == Marker.Length) {
2141 idxs.Add (i - Marker.Length + 1);
2146 public void RenderTemplate (HtmlTextWriter writer, string [] dynamicParts, int start, int count)
2148 if (idxs.Count == 0)
2152 int partEnd = (start == 0) ? -Marker.Length - 1 : (int) idxs [start - 1];
2156 int total = start + count;
2157 for (; i < total; i++) {
2159 partStart = partEnd + Marker.Length + 1;
2160 partEnd = (int) idxs [i];
2162 // write static part
2163 writer.Write (_templateHtml, partStart, partEnd - partStart);
2165 // write synamic part
2166 di = (int) _templateHtml [partEnd + Marker.Length] - 0x971;
2167 writer.Write (dynamicParts [di]);
2170 partStart = partEnd + Marker.Length + 1;
2171 partEnd = (int) idxs [i];
2173 writer.Write (_templateHtml, partStart, partEnd - partStart);