2 // System.Web.UI.WebControls.Menu.cs
5 // Lluis Sanchez Gual (lluis@novell.com)
7 // (C) 2004 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections;
36 using System.ComponentModel;
38 using System.Web.Handlers;
39 using System.Collections.Specialized;
42 namespace System.Web.UI.WebControls
44 public class Menu : HierarchicalDataBoundControl, IPostBackEventHandler, INamingContainer
46 MenuItemStyle dynamicMenuItemStyle;
47 MenuItemStyle dynamicMenuStyle;
48 MenuItemStyle dynamicSelectedStyle;
49 MenuItemStyle staticMenuItemStyle;
50 MenuItemStyle staticMenuStyle;
51 MenuItemStyle staticSelectedStyle;
52 Style staticHoverStyle;
53 Style dynamicHoverStyle;
55 MenuItemStyleCollection levelMenuItemStyles;
56 MenuItemStyleCollection levelSelectedStyles;
58 MenuItemCollection items;
59 MenuItemBindingCollection dataBindings;
60 MenuItem selectedItem;
63 private static readonly object MenuItemClickEvent = new object();
65 public event MenuEventHandler MenuItemClick {
66 add { Events.AddHandler (MenuItemClickEvent, value); }
67 remove { Events.RemoveHandler (MenuItemClickEvent, value); }
70 protected virtual void OnMenuItemClick (MenuEventArgs e)
73 MenuEventHandler eh = (MenuEventHandler) Events [MenuItemClickEvent];
74 if (eh != null) eh (this, e);
78 [PersistenceMode (PersistenceMode.InnerProperty)]
79 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
80 [Editor ("System.Web.UI.Design.MenuItemBindingsEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
81 public virtual MenuItemBindingCollection DataBindings {
83 if (dataBindings == null) {
84 dataBindings = new MenuItemBindingCollection ();
85 if (IsTrackingViewState)
86 ((IStateManager)dataBindings).TrackViewState();
93 public virtual int DisappearAfter {
95 object o = ViewState ["DisappearAfter"];
96 if (o != null) return (int)o;
100 ViewState["DisappearAfter"] = value;
106 [WebCategory ("Appearance")]
107 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
108 public virtual string DynamicBottomSeparatorImageUrl {
110 object o = ViewState ["dbsiu"];
111 if (o != null) return (string)o;
115 ViewState["dbsiu"] = value;
121 [WebCategory ("Appearance")]
122 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
123 public virtual string DynamicTopSeparatorImageUrl {
125 object o = ViewState ["dtsiu"];
126 if (o != null) return (string)o;
130 ViewState["dtsiu"] = value;
136 [WebCategory ("Appearance")]
137 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
138 public virtual string StaticBottomSeparatorImageUrl {
140 object o = ViewState ["sbsiu"];
141 if (o != null) return (string)o;
145 ViewState["sbsiu"] = value;
151 [WebCategory ("Appearance")]
152 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
153 public virtual string StaticTopSeparatorImageUrl {
155 object o = ViewState ["stsiu"];
156 if (o != null) return (string)o;
160 ViewState["stsiu"] = value;
164 [DefaultValue (Orientation.Vertical)]
165 public virtual Orientation Orientation {
167 object o = ViewState ["Orientation"];
168 if (o != null) return (Orientation) o;
169 return Orientation.Vertical;
172 ViewState["Orientation"] = value;
177 public virtual int StaticDisplayLevels {
179 object o = ViewState ["StaticDisplayLevels"];
180 if (o != null) return (int)o;
184 if (value < 1) throw new ArgumentOutOfRangeException ();
185 ViewState["StaticDisplayLevels"] = value;
189 [DefaultValue ("16px")]
190 public Unit StaticSubMenuIndent {
192 object o = ViewState ["StaticSubMenuIndent"];
193 if (o != null) return (Unit)o;
194 return new Unit (16);
197 ViewState["StaticSubMenuIndent"] = value;
202 public virtual int MaximumDynamicDisplayLevels {
204 object o = ViewState ["MaximumDynamicDisplayLevels"];
205 if (o != null) return (int)o;
209 if (value < 0) throw new ArgumentOutOfRangeException ();
210 ViewState["MaximumDynamicDisplayLevels"] = value;
215 public virtual int DynamicVerticalOffset {
217 object o = ViewState ["DynamicVerticalOffset"];
218 if (o != null) return (int)o;
222 ViewState["DynamicVerticalOffset"] = value;
227 public virtual int DynamicHorizontalOffset {
229 object o = ViewState ["DynamicHorizontalOffset"];
230 if (o != null) return (int)o;
234 ViewState["DynamicHorizontalOffset"] = value;
238 [DefaultValue (true)]
239 public virtual bool DynamicEnableDefaultPopOutImage {
241 object o = ViewState ["dedpoi"];
242 if (o != null) return (bool)o;
246 ViewState["dedpoi"] = value;
250 [DefaultValue (true)]
251 public virtual bool StaticEnableDefaultPopOutImage {
253 object o = ViewState ["sedpoi"];
254 if (o != null) return (bool)o;
258 ViewState["sedpoi"] = value;
262 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
263 [PersistenceMode (PersistenceMode.InnerProperty)]
264 [Editor ("System.Web.UI.Design.MenuItemCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
265 public virtual MenuItemCollection Items {
268 items = new MenuItemCollection (this);
269 if (IsTrackingViewState)
270 ((IStateManager)items).TrackViewState();
277 public virtual char PathSeparator {
279 object o = ViewState ["PathSeparator"];
280 if(o != null) return (char)o;
284 ViewState ["PathSeparator"] = value;
288 [DefaultValue (false)]
289 public virtual bool ItemWrap {
291 object o = ViewState ["ItemWrap"];
292 if(o != null) return (bool)o;
296 ViewState ["ItemWrap"] = value;
300 [PersistenceMode (PersistenceMode.InnerProperty)]
301 [NotifyParentProperty (true)]
302 [DefaultValue (null)]
303 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
304 public virtual MenuItemStyle DynamicMenuItemStyle {
306 if (dynamicMenuItemStyle == null) {
307 dynamicMenuItemStyle = new MenuItemStyle ();
308 if (IsTrackingViewState)
309 dynamicMenuItemStyle.TrackViewState();
311 return dynamicMenuItemStyle;
315 [PersistenceMode (PersistenceMode.InnerProperty)]
316 [NotifyParentProperty (true)]
317 [DefaultValue (null)]
318 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
319 public virtual MenuItemStyle DynamicSelectedStyle {
321 if (dynamicSelectedStyle == null) {
322 dynamicSelectedStyle = new MenuItemStyle ();
323 if (IsTrackingViewState)
324 dynamicSelectedStyle.TrackViewState();
326 return dynamicSelectedStyle;
330 [PersistenceMode (PersistenceMode.InnerProperty)]
331 [NotifyParentProperty (true)]
332 [DefaultValue (null)]
333 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
334 public virtual MenuItemStyle DynamicMenuStyle {
336 if (dynamicMenuStyle == null) {
337 dynamicMenuStyle = new MenuItemStyle ();
338 if (IsTrackingViewState)
339 dynamicMenuStyle.TrackViewState();
341 return dynamicMenuStyle;
345 [PersistenceMode (PersistenceMode.InnerProperty)]
346 [NotifyParentProperty (true)]
347 [DefaultValue (null)]
348 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
349 public virtual MenuItemStyle StaticMenuItemStyle {
351 if (staticMenuItemStyle == null) {
352 staticMenuItemStyle = new MenuItemStyle ();
353 if (IsTrackingViewState)
354 staticMenuItemStyle.TrackViewState();
356 return staticMenuItemStyle;
360 [PersistenceMode (PersistenceMode.InnerProperty)]
361 [NotifyParentProperty (true)]
362 [DefaultValue (null)]
363 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
364 public virtual MenuItemStyle StaticSelectedStyle {
366 if (staticSelectedStyle == null) {
367 staticSelectedStyle = new MenuItemStyle ();
368 if (IsTrackingViewState)
369 staticSelectedStyle.TrackViewState();
371 return staticSelectedStyle;
375 [PersistenceMode (PersistenceMode.InnerProperty)]
376 [NotifyParentProperty (true)]
377 [DefaultValue (null)]
378 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
379 public virtual MenuItemStyle StaticMenuStyle {
381 if (staticMenuStyle == null) {
382 staticMenuStyle = new MenuItemStyle ();
383 if (IsTrackingViewState)
384 staticMenuStyle.TrackViewState();
386 return staticMenuStyle;
390 [PersistenceMode (PersistenceMode.InnerProperty)]
391 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
392 public virtual MenuItemStyleCollection LevelMenuItemStyles {
394 if (levelMenuItemStyles == null) {
395 levelMenuItemStyles = new MenuItemStyleCollection ();
396 if (IsTrackingViewState)
397 ((IStateManager)levelMenuItemStyles).TrackViewState();
399 return levelMenuItemStyles;
403 [PersistenceMode (PersistenceMode.InnerProperty)]
404 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
405 public virtual MenuItemStyleCollection LevelSelectedStyles {
407 if (levelSelectedStyles == null) {
408 levelSelectedStyles = new MenuItemStyleCollection ();
409 if (IsTrackingViewState)
410 ((IStateManager)levelSelectedStyles).TrackViewState();
412 return levelSelectedStyles;
416 [PersistenceMode (PersistenceMode.InnerProperty)]
417 [NotifyParentProperty (true)]
418 [DefaultValue (null)]
419 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
420 public virtual Style DynamicHoverStyle {
422 if (dynamicHoverStyle == null) {
423 dynamicHoverStyle = new Style ();
424 if (IsTrackingViewState)
425 dynamicHoverStyle.TrackViewState();
427 return dynamicHoverStyle;
431 [PersistenceMode (PersistenceMode.InnerProperty)]
432 [NotifyParentProperty (true)]
433 [DefaultValue (null)]
434 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
435 public virtual Style StaticHoverStyle {
437 if (staticHoverStyle == null) {
438 staticHoverStyle = new Style ();
439 if (IsTrackingViewState)
440 staticHoverStyle.TrackViewState();
442 return staticHoverStyle;
447 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
448 public MenuItem SelectedItem {
449 get { return selectedItem; }
452 internal void SetSelectedItem (MenuItem item)
454 if (selectedItem == item) return;
455 if (selectedItem != null)
456 selectedItem.SelectedFlag = false;
458 selectedItem.SelectedFlag = true;
461 public MenuItem FindItem (string valuePath)
463 if (valuePath == null) throw new ArgumentNullException ("valuePath");
464 string[] path = valuePath.Split (PathSeparator);
466 MenuItemCollection col = Items;
467 bool foundBranch = true;
468 while (col.Count > 0 && foundBranch) {
470 foreach (MenuItem item in col) {
471 if (item.Value == path [n]) {
472 if (++n == path.Length) return item;
473 col = item.ChildItems;
482 string GetBindingKey (string dataMember, int depth)
484 return dataMember + " " + depth;
487 internal MenuItemBinding FindBindingForItem (string type, int depth)
489 if (bindings == null) return null;
491 MenuItemBinding bin = (MenuItemBinding) bindings [GetBindingKey (type, depth)];
492 if (bin != null) return bin;
494 bin = (MenuItemBinding) bindings [GetBindingKey (type, -1)];
495 if (bin != null) return bin;
497 bin = (MenuItemBinding) bindings [GetBindingKey ("", depth)];
498 if (bin != null) return bin;
500 bin = (MenuItemBinding) bindings [GetBindingKey ("", -1)];
504 protected internal override void PerformDataBinding ()
506 base.PerformDataBinding ();
507 HierarchicalDataSourceView data = GetData ("");
508 IHierarchicalEnumerable e = data.Select ();
509 foreach (object obj in e) {
510 IHierarchyData hdata = e.GetHierarchyData (obj);
511 MenuItem item = new MenuItem ();
517 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
519 MenuItem item = FindItemByPos (eventArgument);
520 if (item == null) return;
521 item.Selected = true;
522 OnMenuItemClick (new MenuEventArgs (item));
525 MenuItem FindItemByPos (string path)
527 string[] indexes = path.Split ('_');
528 MenuItem item = null;
530 foreach (string index in indexes) {
531 int i = int.Parse (index);
533 if (i >= Items.Count) return null;
536 if (i >= item.ChildItems.Count) return null;
537 item = item.ChildItems [i];
543 protected override void TrackViewState()
547 base.TrackViewState();
548 if (dataBindings != null) {
549 ((IStateManager)dataBindings).TrackViewState ();
552 ((IStateManager)items).TrackViewState();
554 if (dynamicMenuItemStyle != null)
555 dynamicMenuItemStyle.TrackViewState ();
556 if (dynamicMenuStyle != null)
557 dynamicMenuStyle.TrackViewState ();
558 if (levelMenuItemStyles != null)
559 ((IStateManager)levelMenuItemStyles).TrackViewState();
560 if (levelSelectedStyles != null)
561 ((IStateManager)levelSelectedStyles).TrackViewState();
562 if (dynamicSelectedStyle != null)
563 dynamicSelectedStyle.TrackViewState();
564 if (staticMenuItemStyle != null)
565 staticMenuItemStyle.TrackViewState ();
566 if (staticMenuStyle != null)
567 staticMenuStyle.TrackViewState ();
568 if (staticSelectedStyle != null)
569 staticSelectedStyle.TrackViewState();
570 if (staticHoverStyle != null)
571 staticHoverStyle.TrackViewState();
572 if (dynamicHoverStyle != null)
573 dynamicHoverStyle.TrackViewState();
576 protected override object SaveViewState()
578 object[] states = new object [13];
579 states[0] = base.SaveViewState ();
580 states[1] = dataBindings == null ? null : ((IStateManager)dataBindings).SaveViewState();
581 states[2] = items == null ? null : ((IStateManager)items).SaveViewState();
582 states[3] = dynamicMenuItemStyle == null ? null : dynamicMenuItemStyle.SaveViewState();
583 states[4] = dynamicMenuStyle == null ? null : dynamicMenuStyle.SaveViewState();
584 states[5] = levelMenuItemStyles == null ? null : ((IStateManager)levelMenuItemStyles).SaveViewState();
585 states[6] = levelSelectedStyles == null ? null : ((IStateManager)levelSelectedStyles).SaveViewState();
586 states[7] = dynamicSelectedStyle == null ? null : dynamicSelectedStyle.SaveViewState();
587 states[8] = (staticMenuItemStyle == null ? null : staticMenuItemStyle.SaveViewState());
588 states[9] = staticMenuStyle == null ? null : staticMenuStyle.SaveViewState();
589 states[10] = staticSelectedStyle == null ? null : staticSelectedStyle.SaveViewState();
590 states[11] = staticHoverStyle == null ? null : staticHoverStyle.SaveViewState();
591 states[12] = dynamicHoverStyle == null ? null : dynamicHoverStyle.SaveViewState();
593 for (int i = states.Length - 1; i >= 0; i--) {
594 if (states [i] != null)
601 protected override void LoadViewState (object savedState)
603 if (savedState == null)
606 object [] states = (object []) savedState;
607 base.LoadViewState (states[0]);
609 if (states[1] != null)
610 ((IStateManager)dataBindings).LoadViewState(states[1]);
611 if (states[2] != null)
612 ((IStateManager)Items).LoadViewState(states[2]);
613 if (states[3] != null)
614 dynamicMenuItemStyle.LoadViewState (states[3]);
615 if (states[4] != null)
616 dynamicMenuStyle.LoadViewState (states[4]);
617 if (states[5] != null)
618 ((IStateManager)levelMenuItemStyles).LoadViewState(states[5]);
619 if (states[6] != null)
620 ((IStateManager)levelSelectedStyles).LoadViewState(states[6]);
621 if (states[7] != null)
622 dynamicSelectedStyle.LoadViewState (states[7]);
623 if (states[8] != null)
624 staticMenuItemStyle.LoadViewState (states[8]);
625 if (states[9] != null)
626 staticMenuStyle.LoadViewState (states[9]);
627 if (states[10] != null)
628 staticSelectedStyle.LoadViewState (states[10]);
629 if (states[11] != null)
630 staticHoverStyle.LoadViewState (states[11]);
631 if (states[12] != null)
632 dynamicHoverStyle.LoadViewState (states[12]);
635 protected override void OnPreRender (EventArgs e)
637 base.OnPreRender (e);
639 if (!Page.ClientScript.IsClientScriptIncludeRegistered (typeof(Menu), "Menu.js")) {
640 string url = Page.GetWebResourceUrl (typeof(Menu), "Menu.js");
641 Page.ClientScript.RegisterClientScriptInclude (typeof(Menu), "Menu.js", url);
644 string cmenu = ClientID + "_data";
645 string script = string.Format ("var {0} = new Object ();\n", cmenu);
646 script += string.Format ("{0}.disappearAfter = {1};\n", cmenu, ClientScriptManager.GetScriptLiteral (DisappearAfter));
647 script += string.Format ("{0}.vertical = {1};\n", cmenu, ClientScriptManager.GetScriptLiteral (Orientation == Orientation.Vertical));
648 if (DynamicHorizontalOffset != 0)
649 script += string.Format ("{0}.dho = {1};\n", cmenu, ClientScriptManager.GetScriptLiteral (DynamicHorizontalOffset));
650 if (DynamicVerticalOffset != 0)
651 script += string.Format ("{0}.dvo = {1};\n", cmenu, ClientScriptManager.GetScriptLiteral (DynamicVerticalOffset));
653 // The order in which styles are defined matters when more than one class
654 // is assigned to an element
656 if (dynamicMenuStyle != null)
657 RegisterItemStyle (dynamicMenuStyle);
658 if (staticMenuStyle != null)
659 RegisterItemStyle (staticMenuStyle);
661 if (staticMenuItemStyle != null)
662 RegisterItemStyle (staticMenuItemStyle);
663 if (staticSelectedStyle != null)
664 RegisterItemStyle (staticSelectedStyle);
666 if (dynamicMenuItemStyle != null)
667 RegisterItemStyle (dynamicMenuItemStyle);
668 if (dynamicSelectedStyle != null)
669 RegisterItemStyle (dynamicSelectedStyle);
671 if (levelMenuItemStyles != null)
672 foreach (Style style in levelMenuItemStyles)
673 RegisterItemStyle (style);
675 if (levelSelectedStyles != null)
676 foreach (Style style in levelSelectedStyles)
677 RegisterItemStyle (style);
679 if (dynamicHoverStyle != null)
680 RegisterItemStyle (dynamicHoverStyle);
681 if (staticHoverStyle != null)
682 RegisterItemStyle (staticHoverStyle);
684 if (staticHoverStyle != null)
685 script += string.Format ("{0}.staticHover = {1};\n", cmenu, ClientScriptManager.GetScriptLiteral (staticHoverStyle.RegisteredCssClass));
686 if (dynamicHoverStyle != null)
687 script += string.Format ("{0}.dynamicHover = {1};\n", cmenu, ClientScriptManager.GetScriptLiteral (dynamicHoverStyle.RegisteredCssClass));
689 Page.ClientScript.RegisterStartupScript (typeof(Menu), ClientID, script, true);
691 if (dataBindings != null && dataBindings.Count > 0) {
692 bindings = new Hashtable ();
693 foreach (TreeNodeBinding bin in dataBindings) {
694 string key = GetBindingKey (bin.DataMember, bin.Depth);
695 bindings [key] = bin;
702 void RegisterItemStyle (Style baseStyle)
704 Page.Header.StyleSheet.RegisterStyle (baseStyle, this);
705 Style ts = new Style ();
706 ts.CopyTextStylesFrom (baseStyle);
707 Page.Header.StyleSheet.CreateStyleRule (ts, "." + baseStyle.RegisteredCssClass + " A", this);
710 protected override void RenderContents (HtmlTextWriter writer)
712 ArrayList dynamicMenus = new ArrayList ();
714 RenderMenu (writer, Items, Orientation == Orientation.Vertical, dynamicMenus, false);
716 for (int n=0; n<dynamicMenus.Count; n++) {
717 MenuItem item = (MenuItem) dynamicMenus [n];
718 writer.AddStyleAttribute ("visibility", "hidden");
719 writer.AddStyleAttribute ("position", "absolute");
720 writer.AddStyleAttribute ("left", "0px");
721 writer.AddStyleAttribute ("top", "0px");
722 writer.AddAttribute ("id", GetItemClientId (item, "s"));
723 writer.RenderBeginTag (HtmlTextWriterTag.Div);
725 RenderMenu (writer, item.ChildItems, true, dynamicMenus, true);
727 writer.RenderEndTag (); // DIV
731 void RenderMenu (HtmlTextWriter writer, MenuItemCollection items, bool vertical, ArrayList dynamicMenus, bool dynamic)
733 writer.AddAttribute ("cellpadding", "0");
734 writer.AddAttribute ("cellspacing", "0");
736 if (dynamic && dynamicMenuStyle != null)
737 writer.AddAttribute ("class", dynamicMenuStyle.RegisteredCssClass);
738 else if (!dynamic && staticMenuStyle != null)
739 writer.AddAttribute ("class", staticMenuStyle.RegisteredCssClass);
741 writer.RenderBeginTag (HtmlTextWriterTag.Table);
742 if (!vertical) writer.RenderBeginTag (HtmlTextWriterTag.Tr);
744 for (int n=0; n<items.Count; n++) {
745 MenuItem item = items [n];
747 int itemSpacing = GetItemSpacing (item, dynamic);
748 if (itemSpacing != 0) {
750 writer.AddAttribute ("height", itemSpacing + "px");
751 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
752 writer.RenderEndTag ();
754 writer.AddAttribute ("width", itemSpacing + "px");
755 writer.RenderBeginTag (HtmlTextWriterTag.Td);
756 writer.RenderEndTag ();
760 RenderMenuItem (writer, item, dynamicMenus);
763 if (!vertical) writer.RenderEndTag (); // TR
764 writer.RenderEndTag (); // TABLE
768 void RenderMenuItem (HtmlTextWriter writer, MenuItem item, ArrayList dynamicMenus)
770 bool displayChildren = (item.Depth + 1 < StaticDisplayLevels + MaximumDynamicDisplayLevels);
771 bool dynamicChildren = displayChildren && (item.Depth + 1 >= StaticDisplayLevels) && item.ChildItems.Count > 0;
772 bool isDynamicItem = item.Depth + 1 > StaticDisplayLevels;
773 bool vertical = (Orientation == Orientation.Vertical) || isDynamicItem;
776 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
778 Style itemStyle = null;
779 if (levelMenuItemStyles != null && item.Depth < levelMenuItemStyles.Count)
780 itemStyle = levelMenuItemStyles [item.Depth];
781 else if (isDynamicItem) {
782 if (dynamicMenuItemStyle != null)
783 itemStyle = dynamicMenuItemStyle;
785 if (staticMenuItemStyle != null)
786 itemStyle = staticMenuItemStyle;
789 Style selectedStyle = null;
790 if (item == SelectedItem) {
791 if (levelSelectedStyles != null && item.Depth < levelSelectedStyles.Count)
792 selectedStyle = levelSelectedStyles [item.Depth];
793 else if (isDynamicItem) {
794 if (dynamicSelectedStyle != null)
795 selectedStyle = dynamicSelectedStyle;
797 if (staticSelectedStyle != null)
798 selectedStyle = staticSelectedStyle;
803 if (itemStyle != null) cls += itemStyle.RegisteredCssClass + " ";
804 if (selectedStyle != null) cls += selectedStyle.RegisteredCssClass + " ";
806 writer.AddAttribute ("class", cls);
808 string parentId = isDynamicItem ? "'" + item.Parent.Path + "'" : "null";
809 if (dynamicChildren) {
810 writer.AddAttribute ("onmouseover", string.Format ("javascript:Menu_OverItem ('{0}','{1}',{2})", ClientID, item.Path, parentId));
811 writer.AddAttribute ("onmouseout", string.Format ("javascript:Menu_OutItem ('{0}','{1}')", ClientID, item.Path));
812 } else if (isDynamicItem) {
813 writer.AddAttribute ("onmouseover", string.Format ("javascript:Menu_OverDynamicLeafItem ('{0}','{1}',{2})", ClientID, item.Path, parentId));
814 writer.AddAttribute ("onmouseout", string.Format ("javascript:Menu_OutItem ('{0}','{1}',{2})", ClientID, item.Path, parentId));
816 writer.AddAttribute ("onmouseover", string.Format ("javascript:Menu_OverStaticLeafItem ('{0}','{1}')", ClientID, item.Path));
817 writer.AddAttribute ("onmouseout", string.Format ("javascript:Menu_OutItem ('{0}','{1}')", ClientID, item.Path));
820 writer.AddAttribute ("id", GetItemClientId (item, "i"));
822 writer.RenderBeginTag (HtmlTextWriterTag.Td);
824 // Bottom separator image
826 if (isDynamicItem && DynamicTopSeparatorImageUrl != "") {
827 writer.AddAttribute ("src", DynamicTopSeparatorImageUrl);
828 writer.RenderBeginTag (HtmlTextWriterTag.Img);
829 writer.RenderEndTag (); // IMG
830 } else if (!isDynamicItem && StaticTopSeparatorImageUrl != "") {
831 writer.AddAttribute ("src", StaticTopSeparatorImageUrl);
832 writer.RenderBeginTag (HtmlTextWriterTag.Img);
833 writer.RenderEndTag (); // IMG
839 writer.AddAttribute ("cellpadding", "0");
840 writer.AddAttribute ("cellspacing", "0");
841 writer.AddAttribute ("width", "100%");
842 writer.RenderBeginTag (HtmlTextWriterTag.Table);
843 writer.RenderBeginTag (HtmlTextWriterTag.Tr);
845 if (item.Depth > 0 && !isDynamicItem) {
846 writer.RenderBeginTag (HtmlTextWriterTag.Td);
847 writer.AddStyleAttribute ("width", StaticSubMenuIndent.ToString ());
848 writer.RenderBeginTag (HtmlTextWriterTag.Div);
849 writer.RenderEndTag (); // DIV
850 writer.RenderEndTag (); // TD
853 if (item.ImageUrl != "") {
854 writer.RenderBeginTag (HtmlTextWriterTag.Td);
855 RenderItemHref (writer, item);
856 writer.RenderBeginTag (HtmlTextWriterTag.A);
857 writer.AddAttribute ("src", item.ImageUrl);
858 writer.AddAttribute ("border", "0");
859 writer.RenderBeginTag (HtmlTextWriterTag.Img);
860 writer.RenderEndTag (); // IMG
861 writer.RenderEndTag (); // A
862 writer.RenderEndTag (); // TD
867 writer.AddAttribute ("width", "100%");
869 writer.AddAttribute ("nowrap", "nowrap");
870 writer.RenderBeginTag (HtmlTextWriterTag.Td);
872 RenderItemHref (writer, item);
873 writer.AddStyleAttribute ("text-decoration", "none");
874 writer.RenderBeginTag (HtmlTextWriterTag.A);
875 writer.Write (item.Text);
876 writer.RenderEndTag (); // A
878 writer.RenderEndTag (); // TD
882 if (dynamicChildren && ((isDynamicItem && DynamicEnableDefaultPopOutImage) || (!isDynamicItem && StaticEnableDefaultPopOutImage) || item.PopOutImageUrl != ""))
884 writer.RenderBeginTag (HtmlTextWriterTag.Td);
887 if (item.PopOutImageUrl != "")
888 src = item.PopOutImageUrl;
890 src = AssemblyResourceLoader.GetResourceUrl (typeof(Menu), "arrow_plus.gif");
892 writer.AddAttribute ("src", src);
893 writer.AddAttribute ("border", "0");
894 writer.RenderBeginTag (HtmlTextWriterTag.Img);
895 writer.RenderEndTag (); // IMG
897 writer.RenderEndTag (); // TD
900 writer.RenderEndTag (); // TR
901 writer.RenderEndTag (); // TABLE
903 // Bottom separator image
905 if (isDynamicItem && DynamicBottomSeparatorImageUrl != "") {
906 writer.AddAttribute ("src", DynamicBottomSeparatorImageUrl);
907 writer.RenderBeginTag (HtmlTextWriterTag.Img);
908 writer.RenderEndTag (); // IMG
909 } else if (!isDynamicItem && StaticBottomSeparatorImageUrl != "") {
910 writer.AddAttribute ("src", StaticBottomSeparatorImageUrl);
911 writer.RenderBeginTag (HtmlTextWriterTag.Img);
912 writer.RenderEndTag (); // IMG
918 if (displayChildren) {
919 if (dynamicChildren) dynamicMenus.Add (item);
921 writer.AddAttribute ("width", "100%");
922 RenderMenu (writer, item.ChildItems, true, dynamicMenus, false);
926 writer.RenderEndTag (); // TD
927 writer.RenderEndTag (); // TR
929 writer.RenderEndTag (); // TD
931 writer.RenderBeginTag (HtmlTextWriterTag.Td);
932 if (displayChildren) {
933 if (dynamicChildren) dynamicMenus.Add (item);
934 else RenderMenu (writer, item.ChildItems, false, dynamicMenus, false);
936 writer.RenderEndTag (); // TD
940 int GetItemSpacing (MenuItem item, bool dynamic)
945 if (levelSelectedStyles != null && item.Depth < levelSelectedStyles.Count) {
946 itemSpacing = levelSelectedStyles [item.Depth].ItemSpacing;
947 if (itemSpacing != 0) return itemSpacing;
950 if (dynamic) itemSpacing = DynamicSelectedStyle.ItemSpacing;
951 else itemSpacing = StaticSelectedStyle.ItemSpacing;
952 if (itemSpacing != 0) return itemSpacing;
955 if (levelMenuItemStyles != null && item.Depth < levelMenuItemStyles.Count) {
956 itemSpacing = levelMenuItemStyles [item.Depth].ItemSpacing;
957 if (itemSpacing != 0) return itemSpacing;
960 if (dynamic) return DynamicMenuItemStyle.ItemSpacing;
961 else return StaticMenuItemStyle.ItemSpacing;
964 void RenderItemHref (HtmlTextWriter writer, MenuItem item)
966 if (item.NavigateUrl != "") {
967 writer.AddAttribute ("href", item.NavigateUrl);
968 if (item.Target != null)
969 writer.AddAttribute ("target", item.Target);
972 writer.AddAttribute ("href", GetClientEvent (item));
976 string GetItemClientId (MenuItem item, string sufix)
978 return ClientID + "_" + item.Path + sufix;
981 string GetClientEvent (MenuItem item)
983 return Page.GetPostBackClientHyperlink (this, item.Path);