2 // System.Web.UI.WebControls.Menu.cs
5 // Lluis Sanchez Gual (lluis@novell.com)
6 // Igor Zelmanovich (igorz@mainsoft.com)
8 // (C) 2004-2010 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.UI.HtmlControls;
40 using System.Web.Handlers;
41 using System.Collections.Specialized;
44 using System.Collections.Generic;
46 namespace System.Web.UI.WebControls
48 [DefaultEvent ("MenuItemClick")]
49 [ControlValueProperty ("SelectedValue")]
50 [Designer ("System.Web.UI.Design.WebControls.MenuDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
51 [SupportsEventValidation]
52 public class Menu : HierarchicalDataBoundControl, IPostBackEventHandler, INamingContainer
54 IMenuRenderer renderer;
56 MenuItemStyle dynamicMenuItemStyle;
57 SubMenuStyle dynamicMenuStyle;
58 MenuItemStyle dynamicSelectedStyle;
59 MenuItemStyle staticMenuItemStyle;
60 SubMenuStyle staticMenuStyle;
61 MenuItemStyle staticSelectedStyle;
62 Style staticHoverStyle;
63 Style dynamicHoverStyle;
65 MenuItemStyleCollection levelMenuItemStyles;
66 MenuItemStyleCollection levelSelectedStyles;
67 SubMenuStyleCollection levelSubMenuStyles;
68 ITemplate staticItemTemplate;
69 ITemplate dynamicItemTemplate;
71 MenuItemCollection items;
72 MenuItemBindingCollection dataBindings;
73 MenuItem selectedItem;
74 string selectedItemPath;
77 Hashtable _menuItemControls;
78 bool _requiresChildControlsDataBinding;
79 SiteMapNode _currSiteMapNode;
80 List<Style> levelSelectedLinkStyles;
81 List<Style> levelMenuItemLinkStyles;
83 Style controlLinkStyle;
84 Style dynamicMenuItemLinkStyle;
85 Style staticMenuItemLinkStyle;
86 Style dynamicSelectedLinkStyle;
87 Style staticSelectedLinkStyle;
88 Style dynamicHoverLinkStyle;
89 Style staticHoverLinkStyle;
92 bool includeStyleBlock = true;
93 MenuRenderingMode renderingMode = MenuRenderingMode.Default;
95 static readonly object MenuItemClickEvent = new object();
96 static readonly object MenuItemDataBoundEvent = new object();
98 public static readonly string MenuItemClickCommandName = "Click";
100 public event MenuEventHandler MenuItemClick {
101 add { Events.AddHandler (MenuItemClickEvent, value); }
102 remove { Events.RemoveHandler (MenuItemClickEvent, value); }
105 public event MenuEventHandler MenuItemDataBound {
106 add { Events.AddHandler (MenuItemDataBoundEvent, value); }
107 remove { Events.RemoveHandler (MenuItemDataBoundEvent, value); }
110 protected virtual void OnMenuItemClick (MenuEventArgs e)
112 if (Events != null) {
113 MenuEventHandler eh = (MenuEventHandler) Events [MenuItemClickEvent];
114 if (eh != null) eh (this, e);
118 protected virtual void OnMenuItemDataBound (MenuEventArgs e)
120 if (Events != null) {
121 MenuEventHandler eh = (MenuEventHandler) Events [MenuItemDataBoundEvent];
122 if (eh != null) eh (this, e);
126 IMenuRenderer Renderer {
128 if (renderer == null)
129 renderer = CreateRenderer (null);
137 if (renderList == null) {
138 switch (RenderingMode) {
139 case MenuRenderingMode.List:
143 case MenuRenderingMode.Table:
148 if (RenderingCompatibilityLessThan40)
156 return renderList.Value;
160 [DefaultValue (true)]
161 [Description ("Determines whether or not to render the inline style block (only used in standards compliance mode)")]
162 public bool IncludeStyleBlock {
163 get { return includeStyleBlock; }
164 set { includeStyleBlock = value; }
167 [DefaultValue (MenuRenderingMode.Default)]
168 public MenuRenderingMode RenderingMode {
169 get { return renderingMode; }
171 if (value < MenuRenderingMode.Default || value > MenuRenderingMode.List)
172 throw new ArgumentOutOfRangeException ("value");
174 renderingMode = value;
175 renderer = CreateRenderer (renderer);
179 [DefaultValueAttribute (null)]
180 [PersistenceMode (PersistenceMode.InnerProperty)]
181 [EditorAttribute ("System.Web.UI.Design.WebControls.MenuBindingsEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
182 [MergablePropertyAttribute (false)]
183 public MenuItemBindingCollection DataBindings {
185 if (dataBindings == null) {
186 dataBindings = new MenuItemBindingCollection ();
187 if (IsTrackingViewState)
188 ((IStateManager)dataBindings).TrackViewState();
195 [ThemeableAttribute (false)]
196 public int DisappearAfter {
198 object o = ViewState ["DisappearAfter"];
199 if (o != null) return (int)o;
203 ViewState["DisappearAfter"] = value;
207 [ThemeableAttribute (true)]
210 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
211 public string DynamicBottomSeparatorImageUrl {
213 object o = ViewState ["dbsiu"];
219 ViewState["dbsiu"] = value;
223 [DefaultValueAttribute ("")]
224 public string DynamicItemFormatString {
226 object o = ViewState ["DynamicItemFormatString"];
227 if (o != null) return (string)o;
231 ViewState["DynamicItemFormatString"] = value;
237 [WebCategory ("Appearance")]
238 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
239 public string DynamicTopSeparatorImageUrl {
241 object o = ViewState ["dtsiu"];
242 if (o != null) return (string)o;
246 ViewState["dtsiu"] = value;
252 [WebCategory ("Appearance")]
253 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
254 public string StaticBottomSeparatorImageUrl {
256 object o = ViewState ["sbsiu"];
257 if (o != null) return (string)o;
261 ViewState["sbsiu"] = value;
267 [WebCategory ("Appearance")]
268 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
269 public string StaticTopSeparatorImageUrl {
271 object o = ViewState ["stsiu"];
272 if (o != null) return (string)o;
276 ViewState["stsiu"] = value;
280 [DefaultValue (Orientation.Vertical)]
281 public Orientation Orientation {
283 object o = ViewState ["Orientation"];
284 if (o != null) return (Orientation) o;
285 return Orientation.Vertical;
288 ViewState["Orientation"] = value;
293 [ThemeableAttribute (true)]
294 public int StaticDisplayLevels {
296 object o = ViewState ["StaticDisplayLevels"];
297 if (o != null) return (int)o;
301 if (value < 1) throw new ArgumentOutOfRangeException ();
302 ViewState["StaticDisplayLevels"] = value;
306 [DefaultValueAttribute ("")]
307 public string StaticItemFormatString {
309 object o = ViewState ["StaticItemFormatString"];
310 if (o != null) return (string)o;
314 ViewState["StaticItemFormatString"] = value;
318 [DefaultValue (typeof (Unit), "16px")]
319 [ThemeableAttribute (true)]
320 public Unit StaticSubMenuIndent {
322 object o = ViewState ["StaticSubMenuIndent"];
325 // LAMESPEC: on 4.0 it returns Unit.Empty and on 3.5 16px
329 return new Unit (16);
333 ViewState["StaticSubMenuIndent"] = value;
337 [ThemeableAttribute (true)]
339 public int MaximumDynamicDisplayLevels {
341 object o = ViewState ["MaximumDynamicDisplayLevels"];
342 if (o != null) return (int)o;
346 if (value < 0) throw new ArgumentOutOfRangeException ();
347 ViewState["MaximumDynamicDisplayLevels"] = value;
352 public int DynamicVerticalOffset {
354 object o = ViewState ["DynamicVerticalOffset"];
355 if (o != null) return (int)o;
359 ViewState["DynamicVerticalOffset"] = value;
364 public int DynamicHorizontalOffset {
366 object o = ViewState ["DynamicHorizontalOffset"];
367 if (o != null) return (int)o;
371 ViewState["DynamicHorizontalOffset"] = value;
375 [DefaultValue (true)]
376 public bool DynamicEnableDefaultPopOutImage {
378 object o = ViewState ["dedpoi"];
379 if (o != null) return (bool)o;
383 ViewState["dedpoi"] = value;
387 [DefaultValue (true)]
388 public bool StaticEnableDefaultPopOutImage {
390 object o = ViewState ["sedpoi"];
391 if (o != null) return (bool)o;
395 ViewState["sedpoi"] = value;
399 [DefaultValueAttribute (null)]
400 [PersistenceMode (PersistenceMode.InnerProperty)]
401 [Editor ("System.Web.UI.Design.MenuItemCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
402 [MergablePropertyAttribute (false)]
403 public MenuItemCollection Items {
406 items = new MenuItemCollection (this);
407 if (IsTrackingViewState)
408 ((IStateManager)items).TrackViewState();
415 public char PathSeparator {
417 object o = ViewState ["PathSeparator"];
418 if(o != null) return (char)o;
422 ViewState ["PathSeparator"] = value;
426 [DefaultValue (false)]
427 public bool ItemWrap {
429 object o = ViewState ["ItemWrap"];
430 if(o != null) return (bool)o;
434 ViewState ["ItemWrap"] = value;
438 internal Style PopOutBoxStyle {
440 if (popOutBoxStyle == null) {
441 popOutBoxStyle = new Style ();
442 popOutBoxStyle.BackColor = Color.White;
444 return popOutBoxStyle;
448 internal Style ControlLinkStyle {
450 if (controlLinkStyle == null) {
451 controlLinkStyle = new Style ();
452 controlLinkStyle.AlwaysRenderTextDecoration = true;
454 return controlLinkStyle;
458 internal Style DynamicMenuItemLinkStyle {
460 if (dynamicMenuItemLinkStyle == null) {
461 dynamicMenuItemLinkStyle = new Style ();
463 return dynamicMenuItemLinkStyle;
467 internal Style StaticMenuItemLinkStyle {
469 if (staticMenuItemLinkStyle == null) {
470 staticMenuItemLinkStyle = new Style ();
472 return staticMenuItemLinkStyle;
476 internal Style DynamicSelectedLinkStyle {
478 if (dynamicSelectedLinkStyle == null) {
479 dynamicSelectedLinkStyle = new Style ();
481 return dynamicSelectedLinkStyle;
485 internal Style StaticSelectedLinkStyle {
487 if (staticSelectedLinkStyle == null) {
488 staticSelectedLinkStyle = new Style ();
490 return staticSelectedLinkStyle;
494 internal Style DynamicHoverLinkStyle {
496 if (dynamicHoverLinkStyle == null) {
497 dynamicHoverLinkStyle = new Style ();
499 return dynamicHoverLinkStyle;
503 internal Style StaticHoverLinkStyle {
505 if (staticHoverLinkStyle == null) {
506 staticHoverLinkStyle = new Style ();
508 return staticHoverLinkStyle;
512 internal MenuItemStyle StaticMenuItemStyleInternal {
513 get { return staticMenuItemStyle; }
516 internal SubMenuStyle StaticMenuStyleInternal {
517 get { return staticMenuStyle; }
520 internal MenuItemStyle DynamicMenuItemStyleInternal {
521 get { return dynamicMenuItemStyle; }
524 internal SubMenuStyle DynamicMenuStyleInternal {
525 get { return dynamicMenuStyle; }
528 internal MenuItemStyleCollection LevelMenuItemStylesInternal {
529 get { return levelMenuItemStyles; }
532 internal List<Style> LevelMenuItemLinkStyles {
533 get { return levelMenuItemLinkStyles; }
536 internal SubMenuStyleCollection LevelSubMenuStylesInternal {
537 get { return levelSubMenuStyles; }
540 internal MenuItemStyle StaticSelectedStyleInternal {
541 get { return staticSelectedStyle; }
544 internal MenuItemStyle DynamicSelectedStyleInternal {
545 get { return dynamicSelectedStyle; }
548 internal MenuItemStyleCollection LevelSelectedStylesInternal {
549 get { return levelSelectedStyles; }
552 internal List<Style> LevelSelectedLinkStyles {
553 get { return levelSelectedLinkStyles; }
556 internal Style StaticHoverStyleInternal {
557 get { return staticHoverStyle; }
560 internal Style DynamicHoverStyleInternal {
561 get { return dynamicHoverStyle; }
564 [PersistenceMode (PersistenceMode.InnerProperty)]
565 [NotifyParentProperty (true)]
566 [DefaultValue (null)]
567 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
568 public MenuItemStyle DynamicMenuItemStyle {
570 if (dynamicMenuItemStyle == null) {
571 dynamicMenuItemStyle = new MenuItemStyle ();
572 if (IsTrackingViewState)
573 dynamicMenuItemStyle.TrackViewState();
575 return dynamicMenuItemStyle;
579 [PersistenceMode (PersistenceMode.InnerProperty)]
580 [NotifyParentProperty (true)]
581 [DefaultValue (null)]
582 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
583 public MenuItemStyle DynamicSelectedStyle {
585 if (dynamicSelectedStyle == null) {
586 dynamicSelectedStyle = new MenuItemStyle ();
587 if (IsTrackingViewState)
588 dynamicSelectedStyle.TrackViewState();
590 return dynamicSelectedStyle;
594 [PersistenceMode (PersistenceMode.InnerProperty)]
595 [NotifyParentProperty (true)]
596 [DefaultValue (null)]
597 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
598 public SubMenuStyle DynamicMenuStyle {
600 if (dynamicMenuStyle == null) {
601 dynamicMenuStyle = new SubMenuStyle ();
602 if (IsTrackingViewState)
603 dynamicMenuStyle.TrackViewState();
605 return dynamicMenuStyle;
609 [PersistenceMode (PersistenceMode.InnerProperty)]
610 [NotifyParentProperty (true)]
611 [DefaultValue (null)]
612 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
613 public MenuItemStyle StaticMenuItemStyle {
615 if (staticMenuItemStyle == null) {
616 staticMenuItemStyle = new MenuItemStyle ();
617 if (IsTrackingViewState)
618 staticMenuItemStyle.TrackViewState();
620 return staticMenuItemStyle;
624 [PersistenceMode (PersistenceMode.InnerProperty)]
625 [NotifyParentProperty (true)]
626 [DefaultValue (null)]
627 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
628 public MenuItemStyle StaticSelectedStyle {
630 if (staticSelectedStyle == null) {
631 staticSelectedStyle = new MenuItemStyle ();
632 if (IsTrackingViewState)
633 staticSelectedStyle.TrackViewState();
635 return staticSelectedStyle;
639 [PersistenceMode (PersistenceMode.InnerProperty)]
640 [NotifyParentProperty (true)]
641 [DefaultValue (null)]
642 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
643 public SubMenuStyle StaticMenuStyle {
645 if (staticMenuStyle == null) {
646 staticMenuStyle = new SubMenuStyle ();
647 if (IsTrackingViewState)
648 staticMenuStyle.TrackViewState();
650 return staticMenuStyle;
654 [DefaultValue (null)]
655 [PersistenceMode (PersistenceMode.InnerProperty)]
656 [Editor ("System.Web.UI.Design.WebControls.MenuItemStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
657 public MenuItemStyleCollection LevelMenuItemStyles {
659 if (levelMenuItemStyles == null) {
660 levelMenuItemStyles = new MenuItemStyleCollection ();
661 if (IsTrackingViewState)
662 ((IStateManager)levelMenuItemStyles).TrackViewState();
664 return levelMenuItemStyles;
668 [DefaultValue (null)]
669 [PersistenceMode (PersistenceMode.InnerProperty)]
670 [Editor ("System.Web.UI.Design.WebControls.MenuItemStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
671 public MenuItemStyleCollection LevelSelectedStyles {
673 if (levelSelectedStyles == null) {
674 levelSelectedStyles = new MenuItemStyleCollection ();
675 if (IsTrackingViewState)
676 ((IStateManager)levelSelectedStyles).TrackViewState();
678 return levelSelectedStyles;
682 [DefaultValue (null)]
683 [PersistenceMode (PersistenceMode.InnerProperty)]
684 [Editor ("System.Web.UI.Design.WebControls.SubMenuStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
685 public SubMenuStyleCollection LevelSubMenuStyles {
687 if (levelSubMenuStyles == null) {
688 levelSubMenuStyles = new SubMenuStyleCollection ();
689 if (IsTrackingViewState)
690 ((IStateManager)levelSubMenuStyles).TrackViewState();
692 return levelSubMenuStyles;
696 [PersistenceMode (PersistenceMode.InnerProperty)]
697 [NotifyParentProperty (true)]
698 [DefaultValue (null)]
699 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
700 public Style DynamicHoverStyle {
702 if (dynamicHoverStyle == null) {
703 dynamicHoverStyle = new Style ();
704 if (IsTrackingViewState)
705 dynamicHoverStyle.TrackViewState();
707 return dynamicHoverStyle;
711 [PersistenceMode (PersistenceMode.InnerProperty)]
712 [NotifyParentProperty (true)]
713 [DefaultValue (null)]
714 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
715 public Style StaticHoverStyle {
717 if (staticHoverStyle == null) {
718 staticHoverStyle = new Style ();
719 if (IsTrackingViewState)
720 staticHoverStyle.TrackViewState();
722 return staticHoverStyle;
728 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
729 public string ScrollDownImageUrl {
731 object o = ViewState ["sdiu"];
732 if (o != null) return (string)o;
736 ViewState["sdiu"] = value;
742 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
743 public string ScrollUpImageUrl {
745 object o = ViewState ["suiu"];
746 if (o != null) return (string)o;
750 ViewState["suiu"] = value;
755 public string ScrollDownText {
757 object o = ViewState ["ScrollDownText"];
758 if (o != null) return (string) o;
759 return Locale.GetText ("Scroll down");
762 ViewState["ScrollDownText"] = value;
767 public string ScrollUpText {
769 object o = ViewState ["ScrollUpText"];
770 if (o != null) return (string) o;
771 return Locale.GetText ("Scroll up");
774 ViewState["ScrollUpText"] = value;
778 public string DynamicPopOutImageTextFormatString
782 object o = ViewState ["dpoitf"];
783 if (o != null) return (string) o;
784 return Locale.GetText ("Expand {0}");
788 ViewState ["dpoitf"] = value;
795 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
796 public string DynamicPopOutImageUrl {
798 object o = ViewState ["dpoiu"];
799 if (o != null) return (string)o;
803 ViewState["dpoiu"] = value;
807 public string StaticPopOutImageTextFormatString
811 object o = ViewState ["spoitf"];
812 if (o != null) return (string) o;
813 return Locale.GetText ("Expand {0}");
817 ViewState ["spoitf"] = value;
824 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
825 public string StaticPopOutImageUrl {
827 object o = ViewState ["spoiu"];
828 if (o != null) return (string)o;
832 ViewState["spoiu"] = value;
837 public string Target {
839 object o = ViewState ["Target"];
840 if (o != null) return (string) o;
844 ViewState["Target"] = value;
848 [DefaultValue (null)]
849 [TemplateContainer (typeof(MenuItemTemplateContainer), BindingDirection.OneWay)]
850 [PersistenceMode (PersistenceMode.InnerProperty)]
852 public ITemplate StaticItemTemplate {
853 get { return staticItemTemplate; }
854 set { staticItemTemplate = value; }
857 [DefaultValue (null)]
858 [TemplateContainer (typeof(MenuItemTemplateContainer), BindingDirection.OneWay)]
859 [PersistenceMode (PersistenceMode.InnerProperty)]
861 public ITemplate DynamicItemTemplate {
862 get { return dynamicItemTemplate; }
863 set { dynamicItemTemplate = value; }
867 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
868 public MenuItem SelectedItem {
870 if (selectedItem == null && selectedItemPath != null) {
871 selectedItem = FindItemByPos (selectedItemPath);
880 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
881 public string SelectedValue {
882 get { return selectedItem != null ? selectedItem.Value : ""; }
886 public string SkipLinkText
889 object o = ViewState ["SkipLinkText"];
892 return "Skip Navigation Links";
895 ViewState ["SkipLinkText"] = value;
899 IMenuRenderer CreateRenderer (IMenuRenderer current)
904 switch (RenderingMode) {
905 case MenuRenderingMode.Default:
906 if (RenderingCompatibilityLessThan40)
907 newType = typeof (MenuTableRenderer);
909 newType = typeof (MenuListRenderer);
912 case MenuRenderingMode.Table:
913 newType = typeof (MenuTableRenderer);
916 case MenuRenderingMode.List:
917 newType = typeof (MenuListRenderer);
924 if (current == null || current.GetType () != newType)
925 return Activator.CreateInstance (newType, this) as IMenuRenderer;
928 return new MenuTableRenderer (this);
933 internal void SetSelectedItem (MenuItem item)
935 if (selectedItem == item) return;
937 selectedItemPath = item.Path;
940 public MenuItem FindItem (string valuePath)
942 if (valuePath == null) throw new ArgumentNullException ("valuePath");
943 string[] path = valuePath.Split (PathSeparator);
945 MenuItemCollection col = Items;
946 bool foundBranch = true;
947 while (col.Count > 0 && foundBranch) {
949 foreach (MenuItem item in col) {
950 if (item.Value == path [n]) {
951 if (++n == path.Length) return item;
952 col = item.ChildItems;
961 string GetBindingKey (string dataMember, int depth)
963 return dataMember + " " + depth;
966 internal MenuItemBinding FindBindingForItem (string type, int depth)
968 if (bindings == null) return null;
970 MenuItemBinding bin = (MenuItemBinding) bindings [GetBindingKey (type, depth)];
971 if (bin != null) return bin;
973 bin = (MenuItemBinding) bindings [GetBindingKey (type, -1)];
974 if (bin != null) return bin;
976 bin = (MenuItemBinding) bindings [GetBindingKey ("", depth)];
977 if (bin != null) return bin;
979 bin = (MenuItemBinding) bindings [GetBindingKey ("", -1)];
983 protected internal override void PerformDataBinding ()
985 base.PerformDataBinding ();
987 // Do not attempt to bind data if there is no
989 if (!IsBoundUsingDataSourceID && (DataSource == null)) {
990 EnsureChildControlsDataBound ();
994 InitializeDataBindings ();
996 HierarchicalDataSourceView data = GetData ("");
999 throw new InvalidOperationException ("No view returned by data source control.");
1002 IHierarchicalEnumerable e = data.Select ();
1003 FillBoundChildrenRecursive (e, Items);
1005 CreateChildControlsForItems ();
1006 ChildControlsCreated = true;
1008 EnsureChildControlsDataBound ();
1011 void FillBoundChildrenRecursive (IHierarchicalEnumerable hEnumerable, MenuItemCollection itemCollection)
1013 if (hEnumerable == null)
1015 foreach (object obj in hEnumerable) {
1016 IHierarchyData hdata = hEnumerable.GetHierarchyData (obj);
1017 MenuItem item = new MenuItem ();
1018 itemCollection.Add (item);
1021 SiteMapNode siteMapNode = hdata as SiteMapNode;
1022 if (siteMapNode != null) {
1023 if (_currSiteMapNode == null)
1024 _currSiteMapNode = siteMapNode.Provider.CurrentNode;
1025 if (siteMapNode == _currSiteMapNode)
1026 item.Selected = true;
1029 OnMenuItemDataBound (new MenuEventArgs (item));
1031 if (hdata == null || !hdata.HasChildren)
1034 IHierarchicalEnumerable e = hdata.GetChildren ();
1035 FillBoundChildrenRecursive (e, item.ChildItems);
1039 protected void SetItemDataBound (MenuItem node, bool dataBound)
1041 node.SetDataBound (dataBound);
1044 protected void SetItemDataPath (MenuItem node, string dataPath)
1046 node.SetDataPath (dataPath);
1049 protected void SetItemDataItem (MenuItem node, object dataItem)
1051 node.SetDataItem (dataItem);
1054 protected internal virtual void RaisePostBackEvent (string eventArgument)
1056 ValidateEvent (UniqueID, eventArgument);
1060 EnsureChildControls();
1061 MenuItem item = FindItemByPos (eventArgument);
1062 if (item == null) return;
1063 item.Selected = true;
1064 OnMenuItemClick (new MenuEventArgs (item));
1067 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
1069 RaisePostBackEvent (eventArgument);
1072 MenuItem FindItemByPos (string path)
1074 string[] indexes = path.Split ('_');
1075 MenuItem item = null;
1077 foreach (string index in indexes) {
1078 int i = int.Parse (index);
1080 if (i >= Items.Count) return null;
1083 if (i >= item.ChildItems.Count) return null;
1084 item = item.ChildItems [i];
1090 protected override HtmlTextWriterTag TagKey {
1091 get { return Renderer.Tag; }
1094 protected override void TrackViewState()
1098 base.TrackViewState();
1099 if (dataBindings != null) {
1100 ((IStateManager)dataBindings).TrackViewState ();
1102 if (items != null) {
1103 ((IStateManager)items).TrackViewState();
1105 if (dynamicMenuItemStyle != null)
1106 dynamicMenuItemStyle.TrackViewState ();
1107 if (dynamicMenuStyle != null)
1108 dynamicMenuStyle.TrackViewState ();
1109 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > 0)
1110 ((IStateManager)levelMenuItemStyles).TrackViewState();
1111 if (levelSelectedStyles != null && levelMenuItemStyles.Count > 0)
1112 ((IStateManager)levelSelectedStyles).TrackViewState();
1113 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0)
1114 ((IStateManager)levelSubMenuStyles).TrackViewState();
1115 if (dynamicSelectedStyle != null)
1116 dynamicSelectedStyle.TrackViewState();
1117 if (staticMenuItemStyle != null)
1118 staticMenuItemStyle.TrackViewState ();
1119 if (staticMenuStyle != null)
1120 staticMenuStyle.TrackViewState ();
1121 if (staticSelectedStyle != null)
1122 staticSelectedStyle.TrackViewState();
1123 if (staticHoverStyle != null)
1124 staticHoverStyle.TrackViewState();
1125 if (dynamicHoverStyle != null)
1126 dynamicHoverStyle.TrackViewState();
1129 protected override object SaveViewState()
1131 object[] states = new object [14];
1132 states[0] = base.SaveViewState ();
1133 states[1] = dataBindings == null ? null : ((IStateManager)dataBindings).SaveViewState();
1134 states[2] = items == null ? null : ((IStateManager)items).SaveViewState();
1135 states[3] = dynamicMenuItemStyle == null ? null : dynamicMenuItemStyle.SaveViewState();
1136 states[4] = dynamicMenuStyle == null ? null : dynamicMenuStyle.SaveViewState();
1137 states[5] = levelMenuItemStyles == null ? null : ((IStateManager)levelMenuItemStyles).SaveViewState();
1138 states[6] = levelSelectedStyles == null ? null : ((IStateManager)levelSelectedStyles).SaveViewState();
1139 states[7] = dynamicSelectedStyle == null ? null : dynamicSelectedStyle.SaveViewState();
1140 states[8] = (staticMenuItemStyle == null ? null : staticMenuItemStyle.SaveViewState());
1141 states[9] = staticMenuStyle == null ? null : staticMenuStyle.SaveViewState();
1142 states[10] = staticSelectedStyle == null ? null : staticSelectedStyle.SaveViewState();
1143 states[11] = staticHoverStyle == null ? null : staticHoverStyle.SaveViewState();
1144 states[12] = dynamicHoverStyle == null ? null : dynamicHoverStyle.SaveViewState();
1145 states[13] = levelSubMenuStyles == null ? null : ((IStateManager)levelSubMenuStyles).SaveViewState();
1147 for (int i = states.Length - 1; i >= 0; i--) {
1148 if (states [i] != null)
1155 protected override void LoadViewState (object savedState)
1157 if (savedState == null)
1160 object [] states = (object []) savedState;
1161 base.LoadViewState (states[0]);
1163 if (states[1] != null)
1164 ((IStateManager)DataBindings).LoadViewState(states[1]);
1165 if (states[2] != null)
1166 ((IStateManager)Items).LoadViewState(states[2]);
1167 if (states[3] != null)
1168 DynamicMenuItemStyle.LoadViewState (states[3]);
1169 if (states[4] != null)
1170 DynamicMenuStyle.LoadViewState (states[4]);
1171 if (states[5] != null)
1172 ((IStateManager)LevelMenuItemStyles).LoadViewState(states[5]);
1173 if (states[6] != null)
1174 ((IStateManager)LevelSelectedStyles).LoadViewState(states[6]);
1175 if (states[7] != null)
1176 DynamicSelectedStyle.LoadViewState (states[7]);
1177 if (states[8] != null)
1178 StaticMenuItemStyle.LoadViewState (states[8]);
1179 if (states[9] != null)
1180 StaticMenuStyle.LoadViewState (states[9]);
1181 if (states[10] != null)
1182 StaticSelectedStyle.LoadViewState (states[10]);
1183 if (states[11] != null)
1184 StaticHoverStyle.LoadViewState (states[11]);
1185 if (states[12] != null)
1186 DynamicHoverStyle.LoadViewState (states[12]);
1187 if (states[13] != null)
1188 ((IStateManager)LevelSubMenuStyles).LoadViewState(states[13]);
1191 protected internal override void OnInit (EventArgs e)
1193 Page.RegisterRequiresControlState (this);
1197 protected internal override void LoadControlState (object ob)
1199 if (ob == null) return;
1200 object[] state = (object[]) ob;
1201 base.LoadControlState (state[0]);
1202 selectedItemPath = state[1] as string;
1205 protected internal override object SaveControlState ()
1207 object bstate = base.SaveControlState ();
1208 object mstate = selectedItemPath;
1210 if (bstate != null || mstate != null)
1211 return new object[] { bstate, mstate };
1216 protected internal override void CreateChildControls ()
1218 if (!IsBoundUsingDataSourceID && (DataSource == null)) {
1219 CreateChildControlsForItems ();
1226 void CreateChildControlsForItems () {
1228 // Check for HasChildViewState to avoid unnecessary calls to ClearChildViewState.
1229 if (HasChildViewState)
1230 ClearChildViewState ();
1231 _menuItemControls = new Hashtable ();
1232 CreateChildControlsForItems (Items);
1233 _requiresChildControlsDataBinding = true;
1236 void CreateChildControlsForItems (MenuItemCollection items )
1238 IMenuRenderer renderer = Renderer;
1239 foreach (MenuItem item in items) {
1240 bool isDynamicItem = renderer.IsDynamicItem (this, item);
1241 if (isDynamicItem && dynamicItemTemplate != null) {
1242 MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
1243 dynamicItemTemplate.InstantiateIn (cter);
1244 _menuItemControls [item] = cter;
1245 Controls.Add (cter);
1247 else if (!isDynamicItem && staticItemTemplate != null) {
1248 MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
1249 staticItemTemplate.InstantiateIn (cter);
1250 _menuItemControls [item] = cter;
1251 Controls.Add (cter);
1253 if (item.HasChildData)
1254 CreateChildControlsForItems (item.ChildItems);
1258 protected override void EnsureDataBound ()
1260 base.EnsureDataBound ();
1262 EnsureChildControlsDataBound ();
1265 void EnsureChildControlsDataBound () {
1266 if (!_requiresChildControlsDataBinding)
1268 DataBindChildren ();
1269 _requiresChildControlsDataBinding = false;
1272 [MonoTODO ("Not implemented")]
1273 protected override IDictionary GetDesignModeState ()
1275 throw new NotImplementedException ();
1278 [MonoTODO ("Not implemented")]
1279 protected override void SetDesignModeState (IDictionary data)
1281 throw new NotImplementedException ();
1284 public override ControlCollection Controls {
1285 get { return base.Controls; }
1288 public sealed override void DataBind ()
1293 protected override bool OnBubbleEvent (object source, EventArgs args)
1295 if (!(args is CommandEventArgs))
1298 MenuEventArgs menuArgs = args as MenuEventArgs;
1299 if (menuArgs != null && string.Equals (menuArgs.CommandName, MenuItemClickCommandName))
1300 OnMenuItemClick (menuArgs);
1304 protected override void OnDataBinding (EventArgs e)
1306 EnsureChildControls ();
1307 base.OnDataBinding (e);
1310 protected internal override void OnPreRender (EventArgs e)
1312 base.OnPreRender (e);
1314 string cmenu = ClientID + "_data";
1315 StringBuilder script = new StringBuilder ();
1318 ClientScriptManager csm;
1321 header = page.Header;
1322 csm = page.ClientScript;
1328 Renderer.PreRender (page, header, csm, cmenu, script);
1331 csm.RegisterWebFormClientScript ();
1332 csm.RegisterStartupScript (typeof(Menu), ClientID, script.ToString (), true);
1336 void InitializeDataBindings () {
1337 if (dataBindings != null && dataBindings.Count > 0) {
1338 bindings = new Hashtable ();
1339 foreach (MenuItemBinding bin in dataBindings) {
1340 string key = GetBindingKey (bin.DataMember, bin.Depth);
1341 bindings [key] = bin;
1348 protected internal override void Render (HtmlTextWriter writer)
1350 if (Items.Count > 0)
1351 base.Render (writer);
1354 protected override void AddAttributesToRender (HtmlTextWriter writer)
1356 Renderer.AddAttributesToRender (writer);
1357 base.AddAttributesToRender (writer);
1360 public override void RenderBeginTag (HtmlTextWriter writer)
1362 string skipLinkText = SkipLinkText;
1363 if (!String.IsNullOrEmpty (skipLinkText))
1364 Renderer.RenderBeginTag (writer, skipLinkText);
1365 base.RenderBeginTag (writer);
1368 public override void RenderEndTag (HtmlTextWriter writer)
1370 base.RenderEndTag (writer);
1372 Renderer.RenderEndTag (writer);
1374 string skipLinkText = SkipLinkText;
1375 if (!String.IsNullOrEmpty (skipLinkText)) {
1376 writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_SkipLink");
1377 writer.RenderBeginTag (HtmlTextWriterTag.A);
1378 writer.RenderEndTag ();
1382 protected internal override void RenderContents (HtmlTextWriter writer)
1384 Renderer.RenderContents (writer);
1387 internal void RenderDynamicMenu (HtmlTextWriter writer, MenuItemCollection items)
1389 for (int n = 0; n < items.Count; n++) {
1390 if (DisplayChildren (items [n])) {
1391 RenderDynamicMenu (writer, items [n]);
1392 RenderDynamicMenu (writer, items [n].ChildItems);
1397 MenuRenderHtmlTemplate _dynamicTemplate;
1398 MenuRenderHtmlTemplate GetDynamicMenuTemplate (MenuItem item)
1400 if (_dynamicTemplate != null)
1401 return _dynamicTemplate;
1403 _dynamicTemplate = new MenuRenderHtmlTemplate ();
1404 HtmlTextWriter writer = _dynamicTemplate.GetMenuTemplateWriter ();
1406 if (Page.Header != null) {
1407 writer.AddAttribute (HtmlTextWriterAttribute.Class, MenuRenderHtmlTemplate.GetMarker (0));
1410 writer.AddAttribute (HtmlTextWriterAttribute.Style, MenuRenderHtmlTemplate.GetMarker (0));
1413 writer.AddStyleAttribute ("visibility", "hidden");
1414 writer.AddStyleAttribute ("position", "absolute");
1415 writer.AddStyleAttribute ("z-index", "1");
1416 writer.AddStyleAttribute ("left", "0px");
1417 writer.AddStyleAttribute ("top", "0px");
1418 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (1));
1419 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1422 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (2));
1423 writer.AddStyleAttribute ("display", "block");
1424 writer.AddStyleAttribute ("text-align", "center");
1425 writer.AddAttribute ("onmouseover", string.Concat ("Menu_OverScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (3), "','u')"));
1426 writer.AddAttribute ("onmouseout", string.Concat ("Menu_OutScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (4), "','u')"));
1427 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1429 writer.AddAttribute ("src", MenuRenderHtmlTemplate.GetMarker (5)); //src
1430 writer.AddAttribute ("alt", MenuRenderHtmlTemplate.GetMarker (6)); //ScrollUpText
1431 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1432 writer.RenderEndTag (); // IMG
1434 writer.RenderEndTag (); // DIV scroll button
1436 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (7));
1437 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1438 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (8));
1439 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1441 // call of RenderMenu
1442 writer.Write (MenuRenderHtmlTemplate.GetMarker (9));
1444 writer.RenderEndTag (); // DIV Content
1445 writer.RenderEndTag (); // DIV Scroll container
1448 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (0));
1449 writer.AddStyleAttribute ("display", "block");
1450 writer.AddStyleAttribute ("text-align", "center");
1451 writer.AddAttribute ("onmouseover", string.Concat ("Menu_OverScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (1), "','d')"));
1452 writer.AddAttribute ("onmouseout", string.Concat ("Menu_OutScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (2), "','d')"));
1453 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1455 writer.AddAttribute ("src", MenuRenderHtmlTemplate.GetMarker (3)); //src
1456 writer.AddAttribute ("alt", MenuRenderHtmlTemplate.GetMarker (4)); //ScrollDownText
1457 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1458 writer.RenderEndTag (); // IMG
1460 writer.RenderEndTag (); // DIV scroll button
1462 writer.RenderEndTag (); // DIV menu
1464 _dynamicTemplate.Parse ();
1465 return _dynamicTemplate;
1468 void RenderDynamicMenu (HtmlTextWriter writer, MenuItem item)
1470 _dynamicTemplate = GetDynamicMenuTemplate (item);
1472 string idPrefix = ClientID + "_" + item.Path;
1473 string [] param = new string [9];
1474 param [0] = GetCssMenuStyle (true, item.Depth + 1);
1475 param [1] = idPrefix + "s";
1476 param [2] = idPrefix + "cu";
1477 param [3] = item.Path;
1478 param [4] = item.Path;
1479 param [5] = ScrollUpImageUrl != "" ? ScrollUpImageUrl : Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_up.gif");
1480 param [6] = ScrollUpText;
1481 param [7] = idPrefix + "cb";
1482 param [8] = idPrefix + "cc";
1484 _dynamicTemplate.RenderTemplate (writer, param, 0, param.Length);
1486 RenderMenu (writer, item.ChildItems, true, true, item.Depth + 1, false);
1488 string [] param2 = new string [5];
1489 param2 [0] = idPrefix + "cd";
1490 param2 [1] = item.Path;
1491 param2 [2] = item.Path;
1492 param2 [3] = ScrollDownImageUrl != "" ? ScrollDownImageUrl : Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_down.gif");
1493 param2 [4] = ScrollDownText;
1495 _dynamicTemplate.RenderTemplate (writer, param2, param.Length + 1, param2.Length);
1499 string GetCssMenuStyle (bool dynamic, int menuLevel)
1501 if (Page.Header != null) {
1502 // styles are registered
1503 StringBuilder sb = new StringBuilder ();
1505 if (!dynamic && staticMenuStyle != null) {
1506 sb.Append (staticMenuStyle.CssClass);
1508 sb.Append (staticMenuStyle.RegisteredCssClass);
1510 if (dynamic && dynamicMenuStyle != null) {
1511 sb.Append (PopOutBoxStyle.RegisteredCssClass);
1513 sb.Append (dynamicMenuStyle.CssClass);
1515 sb.Append (dynamicMenuStyle.RegisteredCssClass);
1517 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
1518 sb.Append (levelSubMenuStyles [menuLevel].CssClass);
1520 sb.Append (levelSubMenuStyles [menuLevel].RegisteredCssClass);
1522 return sb.ToString ();
1525 // styles are not registered
1526 SubMenuStyle style = new SubMenuStyle ();
1528 if (!dynamic && staticMenuStyle != null) {
1529 style.CopyFrom (staticMenuStyle);
1531 if (dynamic && dynamicMenuStyle != null) {
1532 style.CopyFrom (PopOutBoxStyle);
1533 style.CopyFrom (dynamicMenuStyle);
1535 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
1536 style.CopyFrom (levelSubMenuStyles [menuLevel]);
1538 return style.GetStyleAttributes (null).Value;
1542 internal void RenderMenu (HtmlTextWriter writer, MenuItemCollection items, bool vertical, bool dynamic, int menuLevel, bool notLast)
1544 IMenuRenderer renderer = Renderer;
1546 renderer.RenderMenuBeginTag (writer, dynamic, menuLevel);
1547 renderer.RenderMenuBody (writer, items, vertical, dynamic, notLast);
1548 renderer.RenderMenuEndTag (writer, dynamic, menuLevel);
1551 internal bool DisplayChildren (MenuItem item)
1553 return (item.Depth + 1 < StaticDisplayLevels + MaximumDynamicDisplayLevels) && item.ChildItems.Count > 0;
1556 internal void RenderItem (HtmlTextWriter writer, MenuItem item, int position)
1558 // notLast should be true if item or any of its ancestors is not a
1560 bool notLast = false;
1562 MenuItem child = item;
1563 while (null != (parent = child.Parent)) {
1564 if (child.Index != parent.ChildItems.Count - 1) {
1570 Renderer.RenderMenuItem (writer, item, notLast, position == 0);
1573 internal void RenderItemContent (HtmlTextWriter writer, MenuItem item, bool isDynamicItem)
1575 if (_menuItemControls!=null && _menuItemControls [item] != null)
1576 ((Control) _menuItemControls [item]).Render (writer);
1578 Renderer.RenderItemContent (writer, item, isDynamicItem);
1581 internal Unit GetItemSpacing (MenuItem item, bool dynamic)
1583 Unit itemSpacing = Unit.Empty;
1585 if (item.Selected) {
1586 if (levelSelectedStyles != null && item.Depth < levelSelectedStyles.Count) {
1587 itemSpacing = levelSelectedStyles [item.Depth].ItemSpacing;
1588 if (itemSpacing != Unit.Empty) return itemSpacing;
1591 if (dynamic && dynamicSelectedStyle != null)
1592 itemSpacing = dynamicSelectedStyle.ItemSpacing;
1593 else if (!dynamic && staticSelectedStyle != null)
1594 itemSpacing = staticSelectedStyle.ItemSpacing;
1595 if (itemSpacing != Unit.Empty)
1599 if (levelMenuItemStyles != null && item.Depth < levelMenuItemStyles.Count) {
1600 itemSpacing = levelMenuItemStyles [item.Depth].ItemSpacing;
1601 if (itemSpacing != Unit.Empty) return itemSpacing;
1604 if (dynamic && dynamicMenuItemStyle != null)
1605 return dynamicMenuItemStyle.ItemSpacing;
1606 else if (!dynamic && staticMenuItemStyle != null)
1607 return staticMenuItemStyle.ItemSpacing;
1612 class MenuTemplateWriter : TextWriter
1617 public MenuTemplateWriter (char [] buffer)
1622 public override Encoding Encoding
1624 get { return Encoding.Unicode; }
1627 public override void Write (char value)
1629 if (_ptr == _buffer.Length)
1632 _buffer [_ptr++] = value;
1635 public override void Write (string value)
1640 if (_ptr + value.Length >= _buffer.Length)
1643 for (int i = 0; i < value.Length; i++)
1644 _buffer [_ptr++] = value [i];
1647 void EnsureCapacity ()
1649 char [] tmpBuffer = new char [_buffer.Length * 2];
1650 Array.Copy (_buffer, tmpBuffer, _buffer.Length);
1652 _buffer = tmpBuffer;
1656 class MenuRenderHtmlTemplate
1658 public const string Marker = "\u093a\u093b\u0971";
1659 char [] _templateHtml;
1661 MenuTemplateWriter _templateWriter;
1662 ArrayList idxs = new ArrayList (32);
1664 public MenuRenderHtmlTemplate ()
1666 _templateHtml = new char [1024];
1667 _templateWriter = new MenuTemplateWriter (_templateHtml);
1670 public static string GetMarker (int num)
1672 char charNum = (char) ((int) '\u0971' + num);
1673 return string.Concat (Marker, charNum);
1676 public HtmlTextWriter GetMenuTemplateWriter()
1678 return new HtmlTextWriter (_templateWriter);
1681 public void Parse ()
1684 for (int i = 0; i < _templateHtml.Length; i++) {
1685 if (_templateHtml [i] == '\0') {
1690 if (_templateHtml [i] != Marker [mpos]) {
1696 if (mpos == Marker.Length) {
1698 idxs.Add (i - Marker.Length + 1);
1703 public void RenderTemplate (HtmlTextWriter writer, string [] dynamicParts, int start, int count)
1705 if (idxs.Count == 0)
1709 int partEnd = (start == 0) ? -Marker.Length - 1 : (int) idxs [start - 1];
1713 int total = start + count;
1714 for (; i < total; i++) {
1716 partStart = partEnd + Marker.Length + 1;
1717 partEnd = (int) idxs [i];
1719 // write static part
1720 writer.Write (_templateHtml, partStart, partEnd - partStart);
1722 // write synamic part
1723 di = (int) _templateHtml [partEnd + Marker.Length] - 0x971;
1724 writer.Write (dynamicParts [di]);
1727 partStart = partEnd + Marker.Length + 1;
1728 partEnd = (int) idxs [i];
1730 writer.Write (_templateHtml, partStart, partEnd - partStart);