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.
34 using System.Collections;
36 using System.ComponentModel;
38 using System.Web.UI.HtmlControls;
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 IMenuRenderer renderer;
55 MenuItemStyle dynamicMenuItemStyle;
56 SubMenuStyle dynamicMenuStyle;
57 MenuItemStyle dynamicSelectedStyle;
58 MenuItemStyle staticMenuItemStyle;
59 SubMenuStyle staticMenuStyle;
60 MenuItemStyle staticSelectedStyle;
61 Style staticHoverStyle;
62 Style dynamicHoverStyle;
64 MenuItemStyleCollection levelMenuItemStyles;
65 MenuItemStyleCollection levelSelectedStyles;
66 SubMenuStyleCollection levelSubMenuStyles;
67 ITemplate staticItemTemplate;
68 ITemplate dynamicItemTemplate;
70 MenuItemCollection items;
71 MenuItemBindingCollection dataBindings;
72 MenuItem selectedItem;
73 string selectedItemPath;
76 Hashtable _menuItemControls;
77 bool _requiresChildControlsDataBinding;
78 SiteMapNode _currSiteMapNode;
80 Style controlLinkStyle;
81 Style dynamicMenuItemLinkStyle;
82 Style staticMenuItemLinkStyle;
83 Style dynamicSelectedLinkStyle;
84 Style staticSelectedLinkStyle;
85 Style dynamicHoverLinkStyle;
86 Style staticHoverLinkStyle;
88 bool includeStyleBlock = true;
89 MenuRenderingMode renderingMode = MenuRenderingMode.Default;
90 static readonly object MenuItemClickEvent = new object();
91 static readonly object MenuItemDataBoundEvent = new object();
93 public static readonly string MenuItemClickCommandName = "Click";
95 public event MenuEventHandler MenuItemClick {
96 add { Events.AddHandler (MenuItemClickEvent, value); }
97 remove { Events.RemoveHandler (MenuItemClickEvent, value); }
100 public event MenuEventHandler MenuItemDataBound {
101 add { Events.AddHandler (MenuItemDataBoundEvent, value); }
102 remove { Events.RemoveHandler (MenuItemDataBoundEvent, value); }
105 protected virtual void OnMenuItemClick (MenuEventArgs e)
107 if (Events != null) {
108 MenuEventHandler eh = (MenuEventHandler) Events [MenuItemClickEvent];
109 if (eh != null) eh (this, e);
113 protected virtual void OnMenuItemDataBound (MenuEventArgs e)
115 if (Events != null) {
116 MenuEventHandler eh = (MenuEventHandler) Events [MenuItemDataBoundEvent];
117 if (eh != null) eh (this, e);
121 IMenuRenderer Renderer {
123 if (renderer == null)
124 renderer = CreateRenderer (null);
131 if (renderList == null) {
132 switch (RenderingMode) {
133 case MenuRenderingMode.List:
137 case MenuRenderingMode.Table:
142 if (RenderingCompatibilityLessThan40)
150 return renderList.Value;
154 [DefaultValue (true)]
155 [Description ("Determines whether or not to render the inline style block (only used in standards compliance mode)")]
156 public bool IncludeStyleBlock {
157 get { return includeStyleBlock; }
158 set { includeStyleBlock = value; }
161 [DefaultValue (MenuRenderingMode.Default)]
162 public MenuRenderingMode RenderingMode {
163 get { return renderingMode; }
165 if (value < MenuRenderingMode.Default || value > MenuRenderingMode.List)
166 throw new ArgumentOutOfRangeException ("value");
168 renderingMode = value;
169 renderer = CreateRenderer (renderer);
172 [DefaultValueAttribute (null)]
173 [PersistenceMode (PersistenceMode.InnerProperty)]
174 [EditorAttribute ("System.Web.UI.Design.WebControls.MenuBindingsEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
175 [MergablePropertyAttribute (false)]
176 public MenuItemBindingCollection DataBindings {
178 if (dataBindings == null) {
179 dataBindings = new MenuItemBindingCollection ();
180 if (IsTrackingViewState)
181 ((IStateManager)dataBindings).TrackViewState();
188 [ThemeableAttribute (false)]
189 public int DisappearAfter {
191 object o = ViewState ["DisappearAfter"];
192 if (o != null) return (int)o;
196 ViewState["DisappearAfter"] = value;
200 [ThemeableAttribute (true)]
203 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
204 public string DynamicBottomSeparatorImageUrl {
206 object o = ViewState ["dbsiu"];
212 ViewState["dbsiu"] = value;
216 [DefaultValueAttribute ("")]
217 public string DynamicItemFormatString {
219 object o = ViewState ["DynamicItemFormatString"];
220 if (o != null) return (string)o;
224 ViewState["DynamicItemFormatString"] = value;
230 [WebCategory ("Appearance")]
231 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
232 public string DynamicTopSeparatorImageUrl {
234 object o = ViewState ["dtsiu"];
235 if (o != null) return (string)o;
239 ViewState["dtsiu"] = value;
245 [WebCategory ("Appearance")]
246 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
247 public string StaticBottomSeparatorImageUrl {
249 object o = ViewState ["sbsiu"];
250 if (o != null) return (string)o;
254 ViewState["sbsiu"] = value;
260 [WebCategory ("Appearance")]
261 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
262 public string StaticTopSeparatorImageUrl {
264 object o = ViewState ["stsiu"];
265 if (o != null) return (string)o;
269 ViewState["stsiu"] = value;
273 [DefaultValue (Orientation.Vertical)]
274 public Orientation Orientation {
276 object o = ViewState ["Orientation"];
277 if (o != null) return (Orientation) o;
278 return Orientation.Vertical;
281 ViewState["Orientation"] = value;
286 [ThemeableAttribute (true)]
287 public int StaticDisplayLevels {
289 object o = ViewState ["StaticDisplayLevels"];
290 if (o != null) return (int)o;
294 if (value < 1) throw new ArgumentOutOfRangeException ();
295 ViewState["StaticDisplayLevels"] = value;
299 [DefaultValueAttribute ("")]
300 public string StaticItemFormatString {
302 object o = ViewState ["StaticItemFormatString"];
303 if (o != null) return (string)o;
307 ViewState["StaticItemFormatString"] = value;
311 [DefaultValue (typeof (Unit), "16px")]
312 [ThemeableAttribute (true)]
313 public Unit StaticSubMenuIndent {
315 object o = ViewState ["StaticSubMenuIndent"];
318 // LAMESPEC: on 4.0 it returns Unit.Empty and on 3.5 16px
322 ViewState["StaticSubMenuIndent"] = value;
326 [ThemeableAttribute (true)]
328 public int MaximumDynamicDisplayLevels {
330 object o = ViewState ["MaximumDynamicDisplayLevels"];
331 if (o != null) return (int)o;
335 if (value < 0) throw new ArgumentOutOfRangeException ();
336 ViewState["MaximumDynamicDisplayLevels"] = value;
341 public int DynamicVerticalOffset {
343 object o = ViewState ["DynamicVerticalOffset"];
344 if (o != null) return (int)o;
348 ViewState["DynamicVerticalOffset"] = value;
353 public int DynamicHorizontalOffset {
355 object o = ViewState ["DynamicHorizontalOffset"];
356 if (o != null) return (int)o;
360 ViewState["DynamicHorizontalOffset"] = value;
364 [DefaultValue (true)]
365 public bool DynamicEnableDefaultPopOutImage {
367 object o = ViewState ["dedpoi"];
368 if (o != null) return (bool)o;
372 ViewState["dedpoi"] = value;
376 [DefaultValue (true)]
377 public bool StaticEnableDefaultPopOutImage {
379 object o = ViewState ["sedpoi"];
380 if (o != null) return (bool)o;
384 ViewState["sedpoi"] = value;
388 [DefaultValueAttribute (null)]
389 [PersistenceMode (PersistenceMode.InnerProperty)]
390 [Editor ("System.Web.UI.Design.MenuItemCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
391 [MergablePropertyAttribute (false)]
392 public MenuItemCollection Items {
395 items = new MenuItemCollection (this);
396 if (IsTrackingViewState)
397 ((IStateManager)items).TrackViewState();
404 public char PathSeparator {
406 object o = ViewState ["PathSeparator"];
407 if(o != null) return (char)o;
411 ViewState ["PathSeparator"] = value;
415 [DefaultValue (false)]
416 public bool ItemWrap {
418 object o = ViewState ["ItemWrap"];
419 if(o != null) return (bool)o;
423 ViewState ["ItemWrap"] = value;
427 internal Style PopOutBoxStyle {
429 if (popOutBoxStyle == null) {
430 popOutBoxStyle = new Style ();
431 popOutBoxStyle.BackColor = Color.White;
433 return popOutBoxStyle;
437 internal Style ControlLinkStyle {
439 if (controlLinkStyle == null) {
440 controlLinkStyle = new Style ();
441 controlLinkStyle.AlwaysRenderTextDecoration = true;
443 return controlLinkStyle;
447 internal Style DynamicMenuItemLinkStyle {
449 if (dynamicMenuItemLinkStyle == null) {
450 dynamicMenuItemLinkStyle = new Style ();
452 return dynamicMenuItemLinkStyle;
456 internal Style StaticMenuItemLinkStyle {
458 if (staticMenuItemLinkStyle == null) {
459 staticMenuItemLinkStyle = new Style ();
461 return staticMenuItemLinkStyle;
465 internal Style DynamicSelectedLinkStyle {
467 if (dynamicSelectedLinkStyle == null) {
468 dynamicSelectedLinkStyle = new Style ();
470 return dynamicSelectedLinkStyle;
474 internal Style StaticSelectedLinkStyle {
476 if (staticSelectedLinkStyle == null) {
477 staticSelectedLinkStyle = new Style ();
479 return staticSelectedLinkStyle;
483 internal Style DynamicHoverLinkStyle {
485 if (dynamicHoverLinkStyle == null) {
486 dynamicHoverLinkStyle = new Style ();
488 return dynamicHoverLinkStyle;
492 internal Style StaticHoverLinkStyle {
494 if (staticHoverLinkStyle == null) {
495 staticHoverLinkStyle = new Style ();
497 return staticHoverLinkStyle;
501 internal MenuItemStyle StaticMenuItemStyleInternal {
502 get { return staticMenuItemStyle; }
505 internal SubMenuStyle StaticMenuStyleInternal {
506 get { return staticMenuStyle; }
509 internal MenuItemStyle DynamicMenuItemStyleInternal {
510 get { return dynamicMenuItemStyle; }
513 internal SubMenuStyle DynamicMenuStyleInternal {
514 get { return dynamicMenuStyle; }
517 internal MenuItemStyleCollection LevelMenuItemStylesInternal {
518 get { return levelMenuItemStyles; }
521 internal List<Style> LevelMenuItemLinkStyles {
525 internal SubMenuStyleCollection LevelSubMenuStylesInternal {
526 get { return levelSubMenuStyles; }
529 internal MenuItemStyle StaticSelectedStyleInternal {
530 get { return staticSelectedStyle; }
533 internal MenuItemStyle DynamicSelectedStyleInternal {
534 get { return dynamicSelectedStyle; }
537 internal MenuItemStyleCollection LevelSelectedStylesInternal {
538 get { return levelSelectedStyles; }
541 internal List<Style> LevelSelectedLinkStyles {
545 internal Style StaticHoverStyleInternal {
546 get { return staticHoverStyle; }
549 internal Style DynamicHoverStyleInternal {
550 get { return dynamicHoverStyle; }
553 [PersistenceMode (PersistenceMode.InnerProperty)]
554 [NotifyParentProperty (true)]
555 [DefaultValue (null)]
556 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
557 public MenuItemStyle DynamicMenuItemStyle {
559 if (dynamicMenuItemStyle == null) {
560 dynamicMenuItemStyle = new MenuItemStyle ();
561 if (IsTrackingViewState)
562 dynamicMenuItemStyle.TrackViewState();
564 return dynamicMenuItemStyle;
568 [PersistenceMode (PersistenceMode.InnerProperty)]
569 [NotifyParentProperty (true)]
570 [DefaultValue (null)]
571 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
572 public MenuItemStyle DynamicSelectedStyle {
574 if (dynamicSelectedStyle == null) {
575 dynamicSelectedStyle = new MenuItemStyle ();
576 if (IsTrackingViewState)
577 dynamicSelectedStyle.TrackViewState();
579 return dynamicSelectedStyle;
583 [PersistenceMode (PersistenceMode.InnerProperty)]
584 [NotifyParentProperty (true)]
585 [DefaultValue (null)]
586 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
587 public SubMenuStyle DynamicMenuStyle {
589 if (dynamicMenuStyle == null) {
590 dynamicMenuStyle = new SubMenuStyle ();
591 if (IsTrackingViewState)
592 dynamicMenuStyle.TrackViewState();
594 return dynamicMenuStyle;
598 [PersistenceMode (PersistenceMode.InnerProperty)]
599 [NotifyParentProperty (true)]
600 [DefaultValue (null)]
601 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
602 public MenuItemStyle StaticMenuItemStyle {
604 if (staticMenuItemStyle == null) {
605 staticMenuItemStyle = new MenuItemStyle ();
606 if (IsTrackingViewState)
607 staticMenuItemStyle.TrackViewState();
609 return staticMenuItemStyle;
613 [PersistenceMode (PersistenceMode.InnerProperty)]
614 [NotifyParentProperty (true)]
615 [DefaultValue (null)]
616 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
617 public MenuItemStyle StaticSelectedStyle {
619 if (staticSelectedStyle == null) {
620 staticSelectedStyle = new MenuItemStyle ();
621 if (IsTrackingViewState)
622 staticSelectedStyle.TrackViewState();
624 return staticSelectedStyle;
628 [PersistenceMode (PersistenceMode.InnerProperty)]
629 [NotifyParentProperty (true)]
630 [DefaultValue (null)]
631 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
632 public SubMenuStyle StaticMenuStyle {
634 if (staticMenuStyle == null) {
635 staticMenuStyle = new SubMenuStyle ();
636 if (IsTrackingViewState)
637 staticMenuStyle.TrackViewState();
639 return staticMenuStyle;
643 [DefaultValue (null)]
644 [PersistenceMode (PersistenceMode.InnerProperty)]
645 [Editor ("System.Web.UI.Design.WebControls.MenuItemStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
646 public MenuItemStyleCollection LevelMenuItemStyles {
648 if (levelMenuItemStyles == null) {
649 levelMenuItemStyles = new MenuItemStyleCollection ();
650 if (IsTrackingViewState)
651 ((IStateManager)levelMenuItemStyles).TrackViewState();
653 return levelMenuItemStyles;
657 [DefaultValue (null)]
658 [PersistenceMode (PersistenceMode.InnerProperty)]
659 [Editor ("System.Web.UI.Design.WebControls.MenuItemStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
660 public MenuItemStyleCollection LevelSelectedStyles {
662 if (levelSelectedStyles == null) {
663 levelSelectedStyles = new MenuItemStyleCollection ();
664 if (IsTrackingViewState)
665 ((IStateManager)levelSelectedStyles).TrackViewState();
667 return levelSelectedStyles;
671 [DefaultValue (null)]
672 [PersistenceMode (PersistenceMode.InnerProperty)]
673 [Editor ("System.Web.UI.Design.WebControls.SubMenuStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
674 public SubMenuStyleCollection LevelSubMenuStyles {
676 if (levelSubMenuStyles == null) {
677 levelSubMenuStyles = new SubMenuStyleCollection ();
678 if (IsTrackingViewState)
679 ((IStateManager)levelSubMenuStyles).TrackViewState();
681 return levelSubMenuStyles;
685 [PersistenceMode (PersistenceMode.InnerProperty)]
686 [NotifyParentProperty (true)]
687 [DefaultValue (null)]
688 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
689 public Style DynamicHoverStyle {
691 if (dynamicHoverStyle == null) {
692 dynamicHoverStyle = new Style ();
693 if (IsTrackingViewState)
694 dynamicHoverStyle.TrackViewState();
696 return dynamicHoverStyle;
700 [PersistenceMode (PersistenceMode.InnerProperty)]
701 [NotifyParentProperty (true)]
702 [DefaultValue (null)]
703 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
704 public Style StaticHoverStyle {
706 if (staticHoverStyle == null) {
707 staticHoverStyle = new Style ();
708 if (IsTrackingViewState)
709 staticHoverStyle.TrackViewState();
711 return staticHoverStyle;
717 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
718 public string ScrollDownImageUrl {
720 object o = ViewState ["sdiu"];
721 if (o != null) return (string)o;
725 ViewState["sdiu"] = value;
731 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
732 public string ScrollUpImageUrl {
734 object o = ViewState ["suiu"];
735 if (o != null) return (string)o;
739 ViewState["suiu"] = value;
744 public string ScrollDownText {
746 object o = ViewState ["ScrollDownText"];
747 if (o != null) return (string) o;
748 return Locale.GetText ("Scroll down");
751 ViewState["ScrollDownText"] = value;
756 public string ScrollUpText {
758 object o = ViewState ["ScrollUpText"];
759 if (o != null) return (string) o;
760 return Locale.GetText ("Scroll up");
763 ViewState["ScrollUpText"] = value;
767 public string DynamicPopOutImageTextFormatString
771 object o = ViewState ["dpoitf"];
772 if (o != null) return (string) o;
773 return Locale.GetText ("Expand {0}");
777 ViewState ["dpoitf"] = value;
784 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
785 public string DynamicPopOutImageUrl {
787 object o = ViewState ["dpoiu"];
788 if (o != null) return (string)o;
792 ViewState["dpoiu"] = value;
796 public string StaticPopOutImageTextFormatString
800 object o = ViewState ["spoitf"];
801 if (o != null) return (string) o;
802 return Locale.GetText ("Expand {0}");
806 ViewState ["spoitf"] = value;
813 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
814 public string StaticPopOutImageUrl {
816 object o = ViewState ["spoiu"];
817 if (o != null) return (string)o;
821 ViewState["spoiu"] = value;
826 public string Target {
828 object o = ViewState ["Target"];
829 if (o != null) return (string) o;
833 ViewState["Target"] = value;
837 [DefaultValue (null)]
838 [TemplateContainer (typeof(MenuItemTemplateContainer), BindingDirection.OneWay)]
839 [PersistenceMode (PersistenceMode.InnerProperty)]
841 public ITemplate StaticItemTemplate {
842 get { return staticItemTemplate; }
843 set { staticItemTemplate = value; }
846 [DefaultValue (null)]
847 [TemplateContainer (typeof(MenuItemTemplateContainer), BindingDirection.OneWay)]
848 [PersistenceMode (PersistenceMode.InnerProperty)]
850 public ITemplate DynamicItemTemplate {
851 get { return dynamicItemTemplate; }
852 set { dynamicItemTemplate = value; }
856 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
857 public MenuItem SelectedItem {
859 if (selectedItem == null && selectedItemPath != null) {
860 selectedItem = FindItemByPos (selectedItemPath);
869 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
870 public string SelectedValue {
871 get { return selectedItem != null ? selectedItem.Value : ""; }
875 public string SkipLinkText
878 object o = ViewState ["SkipLinkText"];
881 return "Skip Navigation Links";
884 ViewState ["SkipLinkText"] = value;
888 IMenuRenderer CreateRenderer (IMenuRenderer current)
892 switch (RenderingMode) {
893 case MenuRenderingMode.Default:
894 if (RenderingCompatibilityLessThan40)
895 newType = typeof (MenuTableRenderer);
897 newType = typeof (MenuListRenderer);
900 case MenuRenderingMode.Table:
901 newType = typeof (MenuTableRenderer);
904 case MenuRenderingMode.List:
905 newType = typeof (MenuListRenderer);
912 if (current == null || current.GetType () != newType)
913 return Activator.CreateInstance (newType, this) as IMenuRenderer;
917 internal void SetSelectedItem (MenuItem item)
919 if (selectedItem == item) return;
921 selectedItemPath = item.Path;
924 public MenuItem FindItem (string valuePath)
926 if (valuePath == null) throw new ArgumentNullException ("valuePath");
927 string[] path = valuePath.Split (PathSeparator);
929 MenuItemCollection col = Items;
930 bool foundBranch = true;
931 while (col.Count > 0 && foundBranch) {
933 foreach (MenuItem item in col) {
934 if (item.Value == path [n]) {
935 if (++n == path.Length) return item;
936 col = item.ChildItems;
945 string GetBindingKey (string dataMember, int depth)
947 return dataMember + " " + depth;
950 internal MenuItemBinding FindBindingForItem (string type, int depth)
952 if (bindings == null) return null;
954 MenuItemBinding bin = (MenuItemBinding) bindings [GetBindingKey (type, depth)];
955 if (bin != null) return bin;
957 bin = (MenuItemBinding) bindings [GetBindingKey (type, -1)];
958 if (bin != null) return bin;
960 bin = (MenuItemBinding) bindings [GetBindingKey ("", depth)];
961 if (bin != null) return bin;
963 bin = (MenuItemBinding) bindings [GetBindingKey ("", -1)];
967 protected internal override void PerformDataBinding ()
969 base.PerformDataBinding ();
971 // Do not attempt to bind data if there is no
973 if (!IsBoundUsingDataSourceID && (DataSource == null)) {
974 EnsureChildControlsDataBound ();
978 InitializeDataBindings ();
980 HierarchicalDataSourceView data = GetData ("");
983 throw new InvalidOperationException ("No view returned by data source control.");
986 IHierarchicalEnumerable e = data.Select ();
987 FillBoundChildrenRecursive (e, Items);
989 CreateChildControlsForItems ();
990 ChildControlsCreated = true;
992 EnsureChildControlsDataBound ();
995 void FillBoundChildrenRecursive (IHierarchicalEnumerable hEnumerable, MenuItemCollection itemCollection)
997 if (hEnumerable == null)
999 foreach (object obj in hEnumerable) {
1000 IHierarchyData hdata = hEnumerable.GetHierarchyData (obj);
1001 MenuItem item = new MenuItem ();
1002 itemCollection.Add (item);
1005 SiteMapNode siteMapNode = hdata as SiteMapNode;
1006 if (siteMapNode != null) {
1007 if (_currSiteMapNode == null)
1008 _currSiteMapNode = siteMapNode.Provider.CurrentNode;
1009 if (siteMapNode == _currSiteMapNode)
1010 item.Selected = true;
1013 OnMenuItemDataBound (new MenuEventArgs (item));
1015 if (hdata == null || !hdata.HasChildren)
1018 IHierarchicalEnumerable e = hdata.GetChildren ();
1019 FillBoundChildrenRecursive (e, item.ChildItems);
1023 protected void SetItemDataBound (MenuItem node, bool dataBound)
1025 node.SetDataBound (dataBound);
1028 protected void SetItemDataPath (MenuItem node, string dataPath)
1030 node.SetDataPath (dataPath);
1033 protected void SetItemDataItem (MenuItem node, object dataItem)
1035 node.SetDataItem (dataItem);
1038 protected internal virtual void RaisePostBackEvent (string eventArgument)
1040 ValidateEvent (UniqueID, eventArgument);
1044 EnsureChildControls();
1045 MenuItem item = FindItemByPos (eventArgument);
1046 if (item == null) return;
1047 item.Selected = true;
1048 OnMenuItemClick (new MenuEventArgs (item));
1051 void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
1053 RaisePostBackEvent (eventArgument);
1056 MenuItem FindItemByPos (string path)
1058 string[] indexes = path.Split ('_');
1059 MenuItem item = null;
1061 foreach (string index in indexes) {
1062 int i = int.Parse (index);
1064 if (i >= Items.Count) return null;
1067 if (i >= item.ChildItems.Count) return null;
1068 item = item.ChildItems [i];
1074 protected override HtmlTextWriterTag TagKey {
1075 get { return Renderer.Tag; }
1078 protected override void TrackViewState()
1082 base.TrackViewState();
1083 if (dataBindings != null) {
1084 ((IStateManager)dataBindings).TrackViewState ();
1086 if (items != null) {
1087 ((IStateManager)items).TrackViewState();
1089 if (dynamicMenuItemStyle != null)
1090 dynamicMenuItemStyle.TrackViewState ();
1091 if (dynamicMenuStyle != null)
1092 dynamicMenuStyle.TrackViewState ();
1093 if (levelMenuItemStyles != null && levelMenuItemStyles.Count > 0)
1094 ((IStateManager)levelMenuItemStyles).TrackViewState();
1095 if (levelSelectedStyles != null && levelMenuItemStyles.Count > 0)
1096 ((IStateManager)levelSelectedStyles).TrackViewState();
1097 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0)
1098 ((IStateManager)levelSubMenuStyles).TrackViewState();
1099 if (dynamicSelectedStyle != null)
1100 dynamicSelectedStyle.TrackViewState();
1101 if (staticMenuItemStyle != null)
1102 staticMenuItemStyle.TrackViewState ();
1103 if (staticMenuStyle != null)
1104 staticMenuStyle.TrackViewState ();
1105 if (staticSelectedStyle != null)
1106 staticSelectedStyle.TrackViewState();
1107 if (staticHoverStyle != null)
1108 staticHoverStyle.TrackViewState();
1109 if (dynamicHoverStyle != null)
1110 dynamicHoverStyle.TrackViewState();
1113 protected override object SaveViewState()
1115 object[] states = new object [14];
1116 states[0] = base.SaveViewState ();
1117 states[1] = dataBindings == null ? null : ((IStateManager)dataBindings).SaveViewState();
1118 states[2] = items == null ? null : ((IStateManager)items).SaveViewState();
1119 states[3] = dynamicMenuItemStyle == null ? null : dynamicMenuItemStyle.SaveViewState();
1120 states[4] = dynamicMenuStyle == null ? null : dynamicMenuStyle.SaveViewState();
1121 states[5] = levelMenuItemStyles == null ? null : ((IStateManager)levelMenuItemStyles).SaveViewState();
1122 states[6] = levelSelectedStyles == null ? null : ((IStateManager)levelSelectedStyles).SaveViewState();
1123 states[7] = dynamicSelectedStyle == null ? null : dynamicSelectedStyle.SaveViewState();
1124 states[8] = (staticMenuItemStyle == null ? null : staticMenuItemStyle.SaveViewState());
1125 states[9] = staticMenuStyle == null ? null : staticMenuStyle.SaveViewState();
1126 states[10] = staticSelectedStyle == null ? null : staticSelectedStyle.SaveViewState();
1127 states[11] = staticHoverStyle == null ? null : staticHoverStyle.SaveViewState();
1128 states[12] = dynamicHoverStyle == null ? null : dynamicHoverStyle.SaveViewState();
1129 states[13] = levelSubMenuStyles == null ? null : ((IStateManager)levelSubMenuStyles).SaveViewState();
1131 for (int i = states.Length - 1; i >= 0; i--) {
1132 if (states [i] != null)
1139 protected override void LoadViewState (object state)
1144 object [] states = (object []) state;
1145 base.LoadViewState (states[0]);
1147 if (states[1] != null)
1148 ((IStateManager)DataBindings).LoadViewState(states[1]);
1149 if (states[2] != null)
1150 ((IStateManager)Items).LoadViewState(states[2]);
1151 if (states[3] != null)
1152 DynamicMenuItemStyle.LoadViewState (states[3]);
1153 if (states[4] != null)
1154 DynamicMenuStyle.LoadViewState (states[4]);
1155 if (states[5] != null)
1156 ((IStateManager)LevelMenuItemStyles).LoadViewState(states[5]);
1157 if (states[6] != null)
1158 ((IStateManager)LevelSelectedStyles).LoadViewState(states[6]);
1159 if (states[7] != null)
1160 DynamicSelectedStyle.LoadViewState (states[7]);
1161 if (states[8] != null)
1162 StaticMenuItemStyle.LoadViewState (states[8]);
1163 if (states[9] != null)
1164 StaticMenuStyle.LoadViewState (states[9]);
1165 if (states[10] != null)
1166 StaticSelectedStyle.LoadViewState (states[10]);
1167 if (states[11] != null)
1168 StaticHoverStyle.LoadViewState (states[11]);
1169 if (states[12] != null)
1170 DynamicHoverStyle.LoadViewState (states[12]);
1171 if (states[13] != null)
1172 ((IStateManager)LevelSubMenuStyles).LoadViewState(states[13]);
1175 protected internal override void OnInit (EventArgs e)
1177 Page.RegisterRequiresControlState (this);
1181 protected internal override void LoadControlState (object savedState)
1183 if (savedState == null) return;
1184 object[] state = (object[]) savedState;
1185 base.LoadControlState (state[0]);
1186 selectedItemPath = state[1] as string;
1189 protected internal override object SaveControlState ()
1191 object bstate = base.SaveControlState ();
1192 object mstate = selectedItemPath;
1194 if (bstate != null || mstate != null)
1195 return new object[] { bstate, mstate };
1200 protected internal override void CreateChildControls ()
1202 if (!IsBoundUsingDataSourceID && (DataSource == null)) {
1203 CreateChildControlsForItems ();
1210 void CreateChildControlsForItems () {
1212 // Check for HasChildViewState to avoid unnecessary calls to ClearChildViewState.
1213 if (HasChildViewState)
1214 ClearChildViewState ();
1215 _menuItemControls = new Hashtable ();
1216 CreateChildControlsForItems (Items);
1217 _requiresChildControlsDataBinding = true;
1220 void CreateChildControlsForItems (MenuItemCollection items )
1222 IMenuRenderer renderer = Renderer;
1223 foreach (MenuItem item in items) {
1224 bool isDynamicItem = renderer.IsDynamicItem (this, item);
1225 if (isDynamicItem && dynamicItemTemplate != null) {
1226 MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
1227 dynamicItemTemplate.InstantiateIn (cter);
1228 _menuItemControls [item] = cter;
1229 Controls.Add (cter);
1231 else if (!isDynamicItem && staticItemTemplate != null) {
1232 MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
1233 staticItemTemplate.InstantiateIn (cter);
1234 _menuItemControls [item] = cter;
1235 Controls.Add (cter);
1237 if (item.HasChildData)
1238 CreateChildControlsForItems (item.ChildItems);
1242 protected override void EnsureDataBound ()
1244 base.EnsureDataBound ();
1246 EnsureChildControlsDataBound ();
1249 void EnsureChildControlsDataBound () {
1250 if (!_requiresChildControlsDataBinding)
1252 DataBindChildren ();
1253 _requiresChildControlsDataBinding = false;
1256 [MonoTODO ("Not implemented")]
1257 protected override IDictionary GetDesignModeState ()
1259 throw new NotImplementedException ();
1262 [MonoTODO ("Not implemented")]
1263 protected override void SetDesignModeState (IDictionary data)
1265 throw new NotImplementedException ();
1268 public override ControlCollection Controls {
1269 get { return base.Controls; }
1272 public sealed override void DataBind ()
1277 protected override bool OnBubbleEvent (object source, EventArgs e)
1279 if (!(e is CommandEventArgs))
1282 MenuEventArgs menuArgs = e as MenuEventArgs;
1283 if (menuArgs != null && string.Equals (menuArgs.CommandName, MenuItemClickCommandName))
1284 OnMenuItemClick (menuArgs);
1288 protected override void OnDataBinding (EventArgs e)
1290 EnsureChildControls ();
1291 base.OnDataBinding (e);
1294 protected internal override void OnPreRender (EventArgs e)
1296 base.OnPreRender (e);
1298 string cmenu = ClientID + "_data";
1299 StringBuilder script = new StringBuilder ();
1302 ClientScriptManager csm;
1305 header = page.Header;
1306 csm = page.ClientScript;
1312 Renderer.PreRender (page, header, csm, cmenu, script);
1315 csm.RegisterWebFormClientScript ();
1316 csm.RegisterStartupScript (typeof(Menu), ClientID, script.ToString (), true);
1320 void InitializeDataBindings () {
1321 if (dataBindings != null && dataBindings.Count > 0) {
1322 bindings = new Hashtable ();
1323 foreach (MenuItemBinding bin in dataBindings) {
1324 string key = GetBindingKey (bin.DataMember, bin.Depth);
1325 bindings [key] = bin;
1332 protected internal override void Render (HtmlTextWriter writer)
1334 if (Items.Count > 0)
1335 base.Render (writer);
1338 protected override void AddAttributesToRender (HtmlTextWriter writer)
1340 Renderer.AddAttributesToRender (writer);
1341 base.AddAttributesToRender (writer);
1344 public override void RenderBeginTag (HtmlTextWriter writer)
1346 string skipLinkText = SkipLinkText;
1347 if (!String.IsNullOrEmpty (skipLinkText))
1348 Renderer.RenderBeginTag (writer, skipLinkText);
1349 base.RenderBeginTag (writer);
1352 public override void RenderEndTag (HtmlTextWriter writer)
1354 base.RenderEndTag (writer);
1356 Renderer.RenderEndTag (writer);
1358 string skipLinkText = SkipLinkText;
1359 if (!String.IsNullOrEmpty (skipLinkText)) {
1360 writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_SkipLink");
1361 writer.RenderBeginTag (HtmlTextWriterTag.A);
1362 writer.RenderEndTag ();
1366 protected internal override void RenderContents (HtmlTextWriter writer)
1368 Renderer.RenderContents (writer);
1371 internal void RenderDynamicMenu (HtmlTextWriter writer, MenuItemCollection items)
1373 for (int n = 0; n < items.Count; n++) {
1374 if (DisplayChildren (items [n])) {
1375 RenderDynamicMenu (writer, items [n]);
1376 RenderDynamicMenu (writer, items [n].ChildItems);
1381 MenuRenderHtmlTemplate _dynamicTemplate;
1382 MenuRenderHtmlTemplate GetDynamicMenuTemplate (MenuItem item)
1384 if (_dynamicTemplate != null)
1385 return _dynamicTemplate;
1387 _dynamicTemplate = new MenuRenderHtmlTemplate ();
1388 HtmlTextWriter writer = _dynamicTemplate.GetMenuTemplateWriter ();
1390 if (Page.Header != null) {
1391 writer.AddAttribute (HtmlTextWriterAttribute.Class, MenuRenderHtmlTemplate.GetMarker (0));
1394 writer.AddAttribute (HtmlTextWriterAttribute.Style, MenuRenderHtmlTemplate.GetMarker (0));
1397 writer.AddStyleAttribute ("visibility", "hidden");
1398 writer.AddStyleAttribute ("position", "absolute");
1399 writer.AddStyleAttribute ("z-index", "1");
1400 writer.AddStyleAttribute ("left", "0px");
1401 writer.AddStyleAttribute ("top", "0px");
1402 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (1));
1403 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1406 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (2));
1407 writer.AddStyleAttribute ("display", "block");
1408 writer.AddStyleAttribute ("text-align", "center");
1409 writer.AddAttribute ("onmouseover", string.Concat ("Menu_OverScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (3), "','u')"));
1410 writer.AddAttribute ("onmouseout", string.Concat ("Menu_OutScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (4), "','u')"));
1411 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1413 writer.AddAttribute ("src", MenuRenderHtmlTemplate.GetMarker (5)); //src
1414 writer.AddAttribute ("alt", MenuRenderHtmlTemplate.GetMarker (6)); //ScrollUpText
1415 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1416 writer.RenderEndTag (); // IMG
1418 writer.RenderEndTag (); // DIV scroll button
1420 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (7));
1421 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1422 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (8));
1423 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1425 // call of RenderMenu
1426 writer.Write (MenuRenderHtmlTemplate.GetMarker (9));
1428 writer.RenderEndTag (); // DIV Content
1429 writer.RenderEndTag (); // DIV Scroll container
1432 writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (0));
1433 writer.AddStyleAttribute ("display", "block");
1434 writer.AddStyleAttribute ("text-align", "center");
1435 writer.AddAttribute ("onmouseover", string.Concat ("Menu_OverScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (1), "','d')"));
1436 writer.AddAttribute ("onmouseout", string.Concat ("Menu_OutScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (2), "','d')"));
1437 writer.RenderBeginTag (HtmlTextWriterTag.Div);
1439 writer.AddAttribute ("src", MenuRenderHtmlTemplate.GetMarker (3)); //src
1440 writer.AddAttribute ("alt", MenuRenderHtmlTemplate.GetMarker (4)); //ScrollDownText
1441 writer.RenderBeginTag (HtmlTextWriterTag.Img);
1442 writer.RenderEndTag (); // IMG
1444 writer.RenderEndTag (); // DIV scroll button
1446 writer.RenderEndTag (); // DIV menu
1448 _dynamicTemplate.Parse ();
1449 return _dynamicTemplate;
1452 void RenderDynamicMenu (HtmlTextWriter writer, MenuItem item)
1454 _dynamicTemplate = GetDynamicMenuTemplate (item);
1456 string idPrefix = ClientID + "_" + item.Path;
1457 string [] param = new string [9];
1458 param [0] = GetCssMenuStyle (true, item.Depth + 1);
1459 param [1] = idPrefix + "s";
1460 param [2] = idPrefix + "cu";
1461 param [3] = item.Path;
1462 param [4] = item.Path;
1463 param [5] = ScrollUpImageUrl != "" ? ScrollUpImageUrl : Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_up.gif");
1464 param [6] = ScrollUpText;
1465 param [7] = idPrefix + "cb";
1466 param [8] = idPrefix + "cc";
1468 _dynamicTemplate.RenderTemplate (writer, param, 0, param.Length);
1470 RenderMenu (writer, item.ChildItems, true, true, item.Depth + 1, false);
1472 string [] param2 = new string [5];
1473 param2 [0] = idPrefix + "cd";
1474 param2 [1] = item.Path;
1475 param2 [2] = item.Path;
1476 param2 [3] = ScrollDownImageUrl != "" ? ScrollDownImageUrl : Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_down.gif");
1477 param2 [4] = ScrollDownText;
1479 _dynamicTemplate.RenderTemplate (writer, param2, param.Length + 1, param2.Length);
1483 string GetCssMenuStyle (bool dynamic, int menuLevel)
1485 if (Page.Header != null) {
1486 // styles are registered
1487 StringBuilder sb = new StringBuilder ();
1489 if (!dynamic && staticMenuStyle != null) {
1490 sb.Append (staticMenuStyle.CssClass);
1492 sb.Append (staticMenuStyle.RegisteredCssClass);
1494 if (dynamic && dynamicMenuStyle != null) {
1495 sb.Append (PopOutBoxStyle.RegisteredCssClass);
1497 sb.Append (dynamicMenuStyle.CssClass);
1499 sb.Append (dynamicMenuStyle.RegisteredCssClass);
1501 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
1502 sb.Append (levelSubMenuStyles [menuLevel].CssClass);
1504 sb.Append (levelSubMenuStyles [menuLevel].RegisteredCssClass);
1506 return sb.ToString ();
1509 // styles are not registered
1510 SubMenuStyle style = new SubMenuStyle ();
1512 if (!dynamic && staticMenuStyle != null) {
1513 style.CopyFrom (staticMenuStyle);
1515 if (dynamic && dynamicMenuStyle != null) {
1516 style.CopyFrom (PopOutBoxStyle);
1517 style.CopyFrom (dynamicMenuStyle);
1519 if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
1520 style.CopyFrom (levelSubMenuStyles [menuLevel]);
1522 return style.GetStyleAttributes (null).Value;
1526 internal void RenderMenu (HtmlTextWriter writer, MenuItemCollection items, bool vertical, bool dynamic, int menuLevel, bool notLast)
1528 IMenuRenderer renderer = Renderer;
1530 renderer.RenderMenuBeginTag (writer, dynamic, menuLevel);
1531 renderer.RenderMenuBody (writer, items, vertical, dynamic, notLast);
1532 renderer.RenderMenuEndTag (writer, dynamic, menuLevel);
1535 internal bool DisplayChildren (MenuItem item)
1537 return (item.Depth + 1 < StaticDisplayLevels + MaximumDynamicDisplayLevels) && item.ChildItems.Count > 0;
1540 internal void RenderItem (HtmlTextWriter writer, MenuItem item, int position)
1542 // notLast should be true if item or any of its ancestors is not a
1544 bool notLast = false;
1546 MenuItem child = item;
1547 while (null != (parent = child.Parent)) {
1548 if (child.Index != parent.ChildItems.Count - 1) {
1554 Renderer.RenderMenuItem (writer, item, notLast, position == 0);
1557 internal void RenderItemContent (HtmlTextWriter writer, MenuItem item, bool isDynamicItem)
1559 if (_menuItemControls!=null && _menuItemControls [item] != null)
1560 ((Control) _menuItemControls [item]).Render (writer);
1562 Renderer.RenderItemContent (writer, item, isDynamicItem);
1565 internal Unit GetItemSpacing (MenuItem item, bool dynamic)
1567 Unit itemSpacing = Unit.Empty;
1569 if (item.Selected) {
1570 if (levelSelectedStyles != null && item.Depth < levelSelectedStyles.Count) {
1571 itemSpacing = levelSelectedStyles [item.Depth].ItemSpacing;
1572 if (itemSpacing != Unit.Empty) return itemSpacing;
1575 if (dynamic && dynamicSelectedStyle != null)
1576 itemSpacing = dynamicSelectedStyle.ItemSpacing;
1577 else if (!dynamic && staticSelectedStyle != null)
1578 itemSpacing = staticSelectedStyle.ItemSpacing;
1579 if (itemSpacing != Unit.Empty)
1583 if (levelMenuItemStyles != null && item.Depth < levelMenuItemStyles.Count) {
1584 itemSpacing = levelMenuItemStyles [item.Depth].ItemSpacing;
1585 if (itemSpacing != Unit.Empty) return itemSpacing;
1588 if (dynamic && dynamicMenuItemStyle != null)
1589 return dynamicMenuItemStyle.ItemSpacing;
1590 else if (!dynamic && staticMenuItemStyle != null)
1591 return staticMenuItemStyle.ItemSpacing;
1596 class MenuTemplateWriter : TextWriter
1601 public MenuTemplateWriter (char [] buffer)
1606 public override Encoding Encoding
1608 get { return Encoding.Unicode; }
1611 public override void Write (char value)
1613 if (_ptr == _buffer.Length)
1616 _buffer [_ptr++] = value;
1619 public override void Write (string value)
1624 if (_ptr + value.Length >= _buffer.Length)
1627 for (int i = 0; i < value.Length; i++)
1628 _buffer [_ptr++] = value [i];
1631 void EnsureCapacity ()
1633 char [] tmpBuffer = new char [_buffer.Length * 2];
1634 Array.Copy (_buffer, tmpBuffer, _buffer.Length);
1636 _buffer = tmpBuffer;
1640 class MenuRenderHtmlTemplate
1642 public const string Marker = "\u093a\u093b\u0971";
1643 char [] _templateHtml;
1645 MenuTemplateWriter _templateWriter;
1646 ArrayList idxs = new ArrayList (32);
1648 public MenuRenderHtmlTemplate ()
1650 _templateHtml = new char [1024];
1651 _templateWriter = new MenuTemplateWriter (_templateHtml);
1654 public static string GetMarker (int num)
1656 char charNum = (char) ((int) '\u0971' + num);
1657 return string.Concat (Marker, charNum);
1660 public HtmlTextWriter GetMenuTemplateWriter()
1662 return new HtmlTextWriter (_templateWriter);
1665 public void Parse ()
1668 for (int i = 0; i < _templateHtml.Length; i++) {
1669 if (_templateHtml [i] == '\0') {
1674 if (_templateHtml [i] != Marker [mpos]) {
1680 if (mpos == Marker.Length) {
1682 idxs.Add (i - Marker.Length + 1);
1687 public void RenderTemplate (HtmlTextWriter writer, string [] dynamicParts, int start, int count)
1689 if (idxs.Count == 0)
1693 int partEnd = (start == 0) ? -Marker.Length - 1 : (int) idxs [start - 1];
1697 int total = start + count;
1698 for (; i < total; i++) {
1700 partStart = partEnd + Marker.Length + 1;
1701 partEnd = (int) idxs [i];
1703 // write static part
1704 writer.Write (_templateHtml, partStart, partEnd - partStart);
1706 // write synamic part
1707 di = (int) _templateHtml [partEnd + Marker.Length] - 0x971;
1708 writer.Write (dynamicParts [di]);
1711 partStart = partEnd + Marker.Length + 1;
1712 partEnd = (int) idxs [i];
1714 writer.Write (_templateHtml, partStart, partEnd - partStart);