Menu.cs :  » 2.6.4-mono-.net-core » System.Web » System » Web » UI » WebControls » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.Web 
System.Web » System » Web » UI » WebControls » Menu.cs
//
// System.Web.UI.WebControls.Menu.cs
//
// Authors:
//  Lluis Sanchez Gual (lluis@novell.com)
//  Igor Zelmanovich (igorz@mainsoft.com)
//
// (C) 2004 Novell, Inc (http://www.novell.com)
//

//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

#if NET_2_0

using System;
using System.Collections;
using System.Text;
using System.ComponentModel;
using System.Web.UI;
using System.Web.Handlers;
using System.Collections.Specialized;
using System.IO;
using System.Drawing;
using System.Collections.Generic;

namespace System.Web.UI.WebControls{
  [DefaultEvent ("MenuItemClick")]
  [ControlValueProperty ("SelectedValue")]
  [Designer ("System.Web.UI.Design.WebControls.MenuDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
  [SupportsEventValidation]
  public class Menu : HierarchicalDataBoundControl, IPostBackEventHandler, INamingContainer
  {
    MenuItemStyle dynamicMenuItemStyle;
    SubMenuStyle dynamicMenuStyle;
    MenuItemStyle dynamicSelectedStyle;
    MenuItemStyle staticMenuItemStyle;
    SubMenuStyle staticMenuStyle;
    MenuItemStyle staticSelectedStyle;
    Style staticHoverStyle;
    Style dynamicHoverStyle;

    MenuItemStyleCollection levelMenuItemStyles;
    MenuItemStyleCollection levelSelectedStyles;
    SubMenuStyleCollection levelSubMenuStyles;
    ITemplate staticItemTemplate;
    ITemplate dynamicItemTemplate;
    
    MenuItemCollection items;
    MenuItemBindingCollection dataBindings;
    MenuItem selectedItem;
    string selectedItemPath;
    Hashtable bindings;

    Hashtable _menuItemControls;
    bool _requiresChildControlsDataBinding;
    SiteMapNode _currSiteMapNode;
    int registeredStylesCounter = -1;
    List<Style> levelSelectedLinkStyles;
    List<Style> levelMenuItemLinkStyles;
    Style popOutBoxStyle;
    Style controlLinkStyle;
    Style dynamicMenuItemLinkStyle;
    Style staticMenuItemLinkStyle;
    Style dynamicSelectedLinkStyle;
    Style staticSelectedLinkStyle;
    Style dynamicHoverLinkStyle;
    Style staticHoverLinkStyle;

    static readonly object MenuItemClickEvent = new object();
    static readonly object MenuItemDataBoundEvent = new object();
    
    public static readonly string MenuItemClickCommandName = "Click";
    
    public event MenuEventHandler MenuItemClick {
      add { Events.AddHandler (MenuItemClickEvent, value); }
      remove { Events.RemoveHandler (MenuItemClickEvent, value); }
    }
    
    public event MenuEventHandler MenuItemDataBound {
      add { Events.AddHandler (MenuItemDataBoundEvent, value); }
      remove { Events.RemoveHandler (MenuItemDataBoundEvent, value); }
    }
    
    protected virtual void OnMenuItemClick (MenuEventArgs e)
    {
      if (Events != null) {
        MenuEventHandler eh = (MenuEventHandler) Events [MenuItemClickEvent];
        if (eh != null) eh (this, e);
      }
    }
    
    protected virtual void OnMenuItemDataBound (MenuEventArgs e)
    {
      if (Events != null) {
        MenuEventHandler eh = (MenuEventHandler) Events [MenuItemDataBoundEvent];
        if (eh != null) eh (this, e);
      }
    }

    [DefaultValueAttribute (null)]
    [PersistenceMode (PersistenceMode.InnerProperty)]
    [EditorAttribute ("System.Web.UI.Design.WebControls.MenuBindingsEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    [MergablePropertyAttribute (false)]
    public MenuItemBindingCollection DataBindings {
      get {
        if (dataBindings == null) {
          dataBindings = new MenuItemBindingCollection ();
          if (IsTrackingViewState)
            ((IStateManager)dataBindings).TrackViewState();
        }
        return dataBindings;
      }
    }

    [DefaultValue (500)]
    [ThemeableAttribute (false)]
    public int DisappearAfter {
      get {
        object o = ViewState ["DisappearAfter"];
        if (o != null) return (int)o;
        return 500;
      }
      set {
        ViewState["DisappearAfter"] = value;
      }
    }

    [ThemeableAttribute (true)]
    [DefaultValue ("")]
    [UrlProperty]
    [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    public string DynamicBottomSeparatorImageUrl {
      get {
        object o = ViewState ["dbsiu"];
        if (o != null) return (string)o;
        return "";
      }
      set {
        ViewState["dbsiu"] = value;
      }
    }

      [DefaultValueAttribute ("")]
    public string DynamicItemFormatString {
      get {
        object o = ViewState ["DynamicItemFormatString"];
        if (o != null) return (string)o;
        return "";
      }
      set {
        ViewState["DynamicItemFormatString"] = value;
      }
    }

    [DefaultValue ("")]
    [UrlProperty]
    [WebCategory ("Appearance")]
    [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    public string DynamicTopSeparatorImageUrl {
      get {
        object o = ViewState ["dtsiu"];
        if (o != null) return (string)o;
        return "";
      }
      set {
        ViewState["dtsiu"] = value;
      }
    }

    [DefaultValue ("")]
    [UrlProperty]
    [WebCategory ("Appearance")]
    [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    public string StaticBottomSeparatorImageUrl {
      get {
        object o = ViewState ["sbsiu"];
        if (o != null) return (string)o;
        return "";
      }
      set {
        ViewState["sbsiu"] = value;
      }
    }

    [DefaultValue ("")]
    [UrlProperty]
    [WebCategory ("Appearance")]
    [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    public string StaticTopSeparatorImageUrl {
      get {
        object o = ViewState ["stsiu"];
        if (o != null) return (string)o;
        return "";
      }
      set {
        ViewState["stsiu"] = value;
      }
    }

    [DefaultValue (Orientation.Vertical)]
    public Orientation Orientation {
      get {
        object o = ViewState ["Orientation"];
        if (o != null) return (Orientation) o;
        return Orientation.Vertical;
      }
      set {
        ViewState["Orientation"] = value;
      }
    }

    [DefaultValue (1)]
    [ThemeableAttribute (true)]
    public int StaticDisplayLevels {
      get {
        object o = ViewState ["StaticDisplayLevels"];
        if (o != null) return (int)o;
        return 1;
      }
      set {
        if (value < 1) throw new ArgumentOutOfRangeException ();
        ViewState["StaticDisplayLevels"] = value;
      }
    }

      [DefaultValueAttribute ("")]
    public string StaticItemFormatString {
      get {
        object o = ViewState ["StaticItemFormatString"];
        if (o != null) return (string)o;
        return "";
      }
      set {
        ViewState["StaticItemFormatString"] = value;
      }
    }

    [DefaultValue (typeof (Unit), "16px")]
    [ThemeableAttribute (true)]
    public Unit StaticSubMenuIndent {
      get {
        object o = ViewState ["StaticSubMenuIndent"];
        if (o != null) return (Unit)o;
        return new Unit (16);
      }
      set {
        ViewState["StaticSubMenuIndent"] = value;
      }
    }

    [ThemeableAttribute (true)]
    [DefaultValue (3)]
    public int MaximumDynamicDisplayLevels {
      get {
        object o = ViewState ["MaximumDynamicDisplayLevels"];
        if (o != null) return (int)o;
        return 3;
      }
      set {
        if (value < 0) throw new ArgumentOutOfRangeException ();
        ViewState["MaximumDynamicDisplayLevels"] = value;
      }
    }

    [DefaultValue (0)]
    public int DynamicVerticalOffset {
      get {
        object o = ViewState ["DynamicVerticalOffset"];
        if (o != null) return (int)o;
        return 0;
      }
      set {
        ViewState["DynamicVerticalOffset"] = value;
      }
    }

    [DefaultValue (0)]
    public int DynamicHorizontalOffset {
      get {
        object o = ViewState ["DynamicHorizontalOffset"];
        if (o != null) return (int)o;
        return 0;
      }
      set {
        ViewState["DynamicHorizontalOffset"] = value;
      }
    }

    [DefaultValue (true)]
    public bool DynamicEnableDefaultPopOutImage {
      get {
        object o = ViewState ["dedpoi"];
        if (o != null) return (bool)o;
        return true;
      }
      set {
        ViewState["dedpoi"] = value;
      }
    }

    [DefaultValue (true)]
    public bool StaticEnableDefaultPopOutImage {
      get {
        object o = ViewState ["sedpoi"];
        if (o != null) return (bool)o;
        return true;
      }
      set {
        ViewState["sedpoi"] = value;
      }
    }

    [DefaultValueAttribute (null)]
    [PersistenceMode (PersistenceMode.InnerProperty)]
    [Editor ("System.Web.UI.Design.MenuItemCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    [MergablePropertyAttribute (false)]
    public MenuItemCollection Items {
      get {
        if (items == null) {
          items = new MenuItemCollection (this);
          if (IsTrackingViewState)
            ((IStateManager)items).TrackViewState();
        }
        return items;
      }
    }

    [DefaultValue ('/')]
    public char PathSeparator {
      get {
        object o = ViewState ["PathSeparator"];
        if(o != null) return (char)o;
        return '/';
      }
      set {
        ViewState ["PathSeparator"] = value;
      }
    }

    [DefaultValue (false)]
    public bool ItemWrap {
      get {
        object o = ViewState ["ItemWrap"];
        if(o != null) return (bool)o;
        return false;
      }
      set {
        ViewState ["ItemWrap"] = value;
      }
    }

    Style PopOutBoxStyle {
      get {
        if (popOutBoxStyle == null) {
          popOutBoxStyle = new Style ();
          popOutBoxStyle.BackColor = Color.White;
        }
        return popOutBoxStyle;
      }
    }

    Style ControlLinkStyle {
      get {
        if (controlLinkStyle == null) {
          controlLinkStyle = new Style ();
          controlLinkStyle.AlwaysRenderTextDecoration = true;
        }
        return controlLinkStyle;
      }
    }

    Style DynamicMenuItemLinkStyle {
      get {
        if (dynamicMenuItemLinkStyle == null) {
          dynamicMenuItemLinkStyle = new Style ();
        }
        return dynamicMenuItemLinkStyle;
      }
    }

    Style StaticMenuItemLinkStyle {
      get {
        if (staticMenuItemLinkStyle == null) {
          staticMenuItemLinkStyle = new Style ();
        }
        return staticMenuItemLinkStyle;
      }
    }

    Style DynamicSelectedLinkStyle {
      get {
        if (dynamicSelectedLinkStyle == null) {
          dynamicSelectedLinkStyle = new Style ();
        }
        return dynamicSelectedLinkStyle;
      }
    }

    Style StaticSelectedLinkStyle {
      get {
        if (staticSelectedLinkStyle == null) {
          staticSelectedLinkStyle = new Style ();
        }
        return staticSelectedLinkStyle;
      }
    }

    Style DynamicHoverLinkStyle {
      get {
        if (dynamicHoverLinkStyle == null) {
          dynamicHoverLinkStyle = new Style ();
        }
        return dynamicHoverLinkStyle;
      }
    }

    Style StaticHoverLinkStyle {
      get {
        if (staticHoverLinkStyle == null) {
          staticHoverLinkStyle = new Style ();
        }
        return staticHoverLinkStyle;
      }
    }

    [PersistenceMode (PersistenceMode.InnerProperty)]
    [NotifyParentProperty (true)]
    [DefaultValue (null)]
    [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
    public MenuItemStyle DynamicMenuItemStyle {
      get {
        if (dynamicMenuItemStyle == null) {
          dynamicMenuItemStyle = new MenuItemStyle ();
          if (IsTrackingViewState)
            dynamicMenuItemStyle.TrackViewState();
        }
        return dynamicMenuItemStyle;
      }
    }
    
    [PersistenceMode (PersistenceMode.InnerProperty)]
    [NotifyParentProperty (true)]
    [DefaultValue (null)]
    [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
    public MenuItemStyle DynamicSelectedStyle {
      get {
        if (dynamicSelectedStyle == null) {
          dynamicSelectedStyle = new MenuItemStyle ();
          if (IsTrackingViewState)
            dynamicSelectedStyle.TrackViewState();
        }
        return dynamicSelectedStyle;
      }
    }
    
    [PersistenceMode (PersistenceMode.InnerProperty)]
    [NotifyParentProperty (true)]
    [DefaultValue (null)]
    [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
    public SubMenuStyle DynamicMenuStyle {
      get {
        if (dynamicMenuStyle == null) {
          dynamicMenuStyle = new SubMenuStyle ();
          if (IsTrackingViewState)
            dynamicMenuStyle.TrackViewState();
        }
        return dynamicMenuStyle;
      }
    }
    
    [PersistenceMode (PersistenceMode.InnerProperty)]
    [NotifyParentProperty (true)]
    [DefaultValue (null)]
    [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
    public MenuItemStyle StaticMenuItemStyle {
      get {
        if (staticMenuItemStyle == null) {
          staticMenuItemStyle = new MenuItemStyle ();
          if (IsTrackingViewState)
            staticMenuItemStyle.TrackViewState();
        }
        return staticMenuItemStyle;
      }
    }
    
    [PersistenceMode (PersistenceMode.InnerProperty)]
    [NotifyParentProperty (true)]
    [DefaultValue (null)]
    [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
    public MenuItemStyle StaticSelectedStyle {
      get {
        if (staticSelectedStyle == null) {
          staticSelectedStyle = new MenuItemStyle ();
          if (IsTrackingViewState)
            staticSelectedStyle.TrackViewState();
        }
        return staticSelectedStyle;
      }
    }
    
    [PersistenceMode (PersistenceMode.InnerProperty)]
    [NotifyParentProperty (true)]
    [DefaultValue (null)]
    [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
    public SubMenuStyle StaticMenuStyle {
      get {
        if (staticMenuStyle == null) {
          staticMenuStyle = new SubMenuStyle ();
          if (IsTrackingViewState)
            staticMenuStyle.TrackViewState();
        }
        return staticMenuStyle;
      }
    }

    [DefaultValue (null)]
    [PersistenceMode (PersistenceMode.InnerProperty)]
      [Editor ("System.Web.UI.Design.WebControls.MenuItemStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    public MenuItemStyleCollection LevelMenuItemStyles {
      get {
        if (levelMenuItemStyles == null) {
          levelMenuItemStyles = new MenuItemStyleCollection ();
          if (IsTrackingViewState)
            ((IStateManager)levelMenuItemStyles).TrackViewState();
        }
        return levelMenuItemStyles;
      }
    }

    [DefaultValue (null)]
    [PersistenceMode (PersistenceMode.InnerProperty)]
      [Editor ("System.Web.UI.Design.WebControls.MenuItemStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    public MenuItemStyleCollection LevelSelectedStyles {
      get {
        if (levelSelectedStyles == null) {
          levelSelectedStyles = new MenuItemStyleCollection ();
          if (IsTrackingViewState)
            ((IStateManager)levelSelectedStyles).TrackViewState();
        }
        return levelSelectedStyles;
      }
    }

    [DefaultValue (null)]
    [PersistenceMode (PersistenceMode.InnerProperty)]
      [Editor ("System.Web.UI.Design.WebControls.SubMenuStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    public SubMenuStyleCollection LevelSubMenuStyles {
      get {
        if (levelSubMenuStyles == null) {
          levelSubMenuStyles = new SubMenuStyleCollection ();
          if (IsTrackingViewState)
            ((IStateManager)levelSubMenuStyles).TrackViewState();
        }
        return levelSubMenuStyles;
      }
    }

    [PersistenceMode (PersistenceMode.InnerProperty)]
    [NotifyParentProperty (true)]
    [DefaultValue (null)]
    [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
    public Style DynamicHoverStyle {
      get {
        if (dynamicHoverStyle == null) {
          dynamicHoverStyle = new Style ();
          if (IsTrackingViewState)
            dynamicHoverStyle.TrackViewState();
        }
        return dynamicHoverStyle;
      }
    }
    
    [PersistenceMode (PersistenceMode.InnerProperty)]
    [NotifyParentProperty (true)]
    [DefaultValue (null)]
    [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
    public Style StaticHoverStyle {
      get {
        if (staticHoverStyle == null) {
          staticHoverStyle = new Style ();
          if (IsTrackingViewState)
            staticHoverStyle.TrackViewState();
        }
        return staticHoverStyle;
      }
    }
    
    [DefaultValue ("")]
    [UrlProperty]
    [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    public string ScrollDownImageUrl {
      get {
        object o = ViewState ["sdiu"];
        if (o != null) return (string)o;
        return "";
      }
      set {
        ViewState["sdiu"] = value;
      }
    }

    [DefaultValue ("")]
    [UrlProperty]
    [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    public string ScrollUpImageUrl {
      get {
        object o = ViewState ["suiu"];
        if (o != null) return (string)o;
        return "";
      }
      set {
        ViewState["suiu"] = value;
      }
    }

    [Localizable (true)]
    public string ScrollDownText {
      get {
        object o = ViewState ["ScrollDownText"];
        if (o != null) return (string) o;
        return Locale.GetText ("Scroll down");
      }
      set {
        ViewState["ScrollDownText"] = value;
      }
    }

    [Localizable (true)]
    public string ScrollUpText {
      get {
        object o = ViewState ["ScrollUpText"];
        if (o != null) return (string) o;
        return Locale.GetText ("Scroll up");
      }
      set {
        ViewState["ScrollUpText"] = value;
      }
    }

    public string DynamicPopOutImageTextFormatString 
    {
      get
      {
        object o = ViewState ["dpoitf"];
        if (o != null) return (string) o;
        return Locale.GetText ("Expand {0}");
      }
      set
      {
        ViewState ["dpoitf"] = value;
      }
    }
    

    [DefaultValue ("")]
    [UrlProperty]
    [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    public string DynamicPopOutImageUrl {
      get {
        object o = ViewState ["dpoiu"];
        if (o != null) return (string)o;
        return "";
      }
      set {
        ViewState["dpoiu"] = value;
      }
    }

    public string StaticPopOutImageTextFormatString
    {
      get
      {
        object o = ViewState ["spoitf"];
        if (o != null) return (string) o;
        return Locale.GetText ("Expand {0}");
      }
      set
      {
        ViewState ["spoitf"] = value;
      }
    }
    

    [DefaultValue ("")]
    [UrlProperty]
    [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
    public string StaticPopOutImageUrl {
      get {
        object o = ViewState ["spoiu"];
        if (o != null) return (string)o;
        return "";
      }
      set {
        ViewState["spoiu"] = value;
      }
    }

    [DefaultValue ("")]
    public string Target {
      get {
        object o = ViewState ["Target"];
        if (o != null) return (string) o;
        return "";
      }
      set {
        ViewState["Target"] = value;
      }
    }

    [DefaultValue (null)]
    [TemplateContainer (typeof(MenuItemTemplateContainer), BindingDirection.OneWay)]
    [PersistenceMode (PersistenceMode.InnerProperty)]
      [Browsable (false)]
    public ITemplate StaticItemTemplate {
      get { return staticItemTemplate; }
      set { staticItemTemplate = value; }
    }
    
    [DefaultValue (null)]
    [TemplateContainer (typeof(MenuItemTemplateContainer), BindingDirection.OneWay)]
    [PersistenceMode (PersistenceMode.InnerProperty)]
      [Browsable (false)]
    public ITemplate DynamicItemTemplate {
      get { return dynamicItemTemplate; }
      set { dynamicItemTemplate = value; }
    }
    
    [Browsable (false)]
    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
    public MenuItem SelectedItem {
      get {
        if (selectedItem == null && selectedItemPath != null) {
          selectedItem = FindItemByPos (selectedItemPath);
        }
        
        return selectedItem;
      }
    }

    [Browsable (false)]
    [DefaultValue ("")]
    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
    public string SelectedValue {
      get { return selectedItem != null ? selectedItem.Value : ""; }
    }

    [Localizable (true)]
    public string SkipLinkText 
    {
      get {
        object o = ViewState ["SkipLinkText"];
        if (o != null)
          return (string) o;
        return "Skip Navigation Links";
      }
      set {
        ViewState ["SkipLinkText"] = value;
      }
    }
    

    internal void SetSelectedItem (MenuItem item)
    {
      if (selectedItem == item) return;
      selectedItem = item;
      selectedItemPath = item.Path;
    }
    
    public MenuItem FindItem (string valuePath)
    {
      if (valuePath == null) throw new ArgumentNullException ("valuePath");
      string[] path = valuePath.Split (PathSeparator);
      int n = 0;
      MenuItemCollection col = Items;
      bool foundBranch = true;
      while (col.Count > 0 && foundBranch) {
        foundBranch = false;
        foreach (MenuItem item in col) {
          if (item.Value == path [n]) {
            if (++n == path.Length) return item;
            col = item.ChildItems;
            foundBranch = true;
            break;
          }
        }
      }
      return null;
    }
    
    string GetBindingKey (string dataMember, int depth)
    {
      return dataMember + " " + depth;
    }
    
    internal MenuItemBinding FindBindingForItem (string type, int depth)
    {
      if (bindings == null) return null;

      MenuItemBinding bin = (MenuItemBinding) bindings [GetBindingKey (type, depth)];
      if (bin != null) return bin;
      
      bin = (MenuItemBinding) bindings [GetBindingKey (type, -1)];
      if (bin != null) return bin;
      
      bin = (MenuItemBinding) bindings [GetBindingKey ("", depth)];
      if (bin != null) return bin;
      
      bin = (MenuItemBinding) bindings [GetBindingKey ("", -1)];
      return bin;
    }
    
    protected internal override void PerformDataBinding ()
    {
      base.PerformDataBinding ();

      // Do not attempt to bind data if there is no
      // data source set.
      if (!IsBoundUsingDataSourceID && (DataSource == null)) {
        EnsureChildControlsDataBound ();
        return;
      }

      InitializeDataBindings ();

      HierarchicalDataSourceView data = GetData ("");

      if (data == null) {
        throw new InvalidOperationException ("No view returned by data source control.");
      }
      Items.Clear ();
      IHierarchicalEnumerable e = data.Select ();
      FillBoundChildrenRecursive (e, Items);

      CreateChildControlsForItems ();
      ChildControlsCreated = true;

      EnsureChildControlsDataBound ();
    }

    void FillBoundChildrenRecursive (IHierarchicalEnumerable hEnumerable, MenuItemCollection itemCollection)
    {
      if (hEnumerable == null)
        return;
      foreach (object obj in hEnumerable) {
        IHierarchyData hdata = hEnumerable.GetHierarchyData (obj);
        MenuItem item = new MenuItem ();
        itemCollection.Add (item);
        item.Bind (hdata);

        SiteMapNode siteMapNode = hdata as SiteMapNode;
        if (siteMapNode != null) {
          if (_currSiteMapNode == null)
            _currSiteMapNode = siteMapNode.Provider.CurrentNode;
          if (siteMapNode == _currSiteMapNode)
            item.Selected = true;
        }
        
        OnMenuItemDataBound (new MenuEventArgs (item));

        if (hdata == null || !hdata.HasChildren)
          continue;

        IHierarchicalEnumerable e = hdata.GetChildren ();
        FillBoundChildrenRecursive (e, item.ChildItems);
      }
    }
    
    protected void SetItemDataBound (MenuItem node, bool dataBound)
    {
      node.SetDataBound (dataBound);
    }
    
    protected void SetItemDataPath (MenuItem node, string dataPath)
    {
      node.SetDataPath (dataPath);
    }
    
    protected void SetItemDataItem (MenuItem node, object dataItem)
    {
      node.SetDataItem (dataItem);
    }
    
    protected internal virtual void RaisePostBackEvent (string eventArgument)
    {
      ValidateEvent (UniqueID, eventArgument);
      if (!Enabled)
        return;

      EnsureChildControls();
      MenuItem item = FindItemByPos (eventArgument);
      if (item == null) return;
      item.Selected = true;
      OnMenuItemClick (new MenuEventArgs (item));
    }

    void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
    {
      RaisePostBackEvent (eventArgument);
    }
    
    MenuItem FindItemByPos (string path)
    {
      string[] indexes = path.Split ('_');
      MenuItem item = null;
      
      foreach (string index in indexes) {
        int i = int.Parse (index);
        if (item == null) {
          if (i >= Items.Count) return null;
          item = Items [i];
        } else {
          if (i >= item.ChildItems.Count) return null;
          item = item.ChildItems [i];
        }
      }
      return item;
    }
    
    protected override HtmlTextWriterTag TagKey {
      get { return HtmlTextWriterTag.Table; }
    }
    
    protected override void TrackViewState()
    {
      EnsureDataBound ();
      
      base.TrackViewState();
      if (dataBindings != null) {
        ((IStateManager)dataBindings).TrackViewState ();
      }
      if (items != null) {
        ((IStateManager)items).TrackViewState();
      }
      if (dynamicMenuItemStyle != null)
        dynamicMenuItemStyle.TrackViewState ();
      if (dynamicMenuStyle != null)
        dynamicMenuStyle.TrackViewState ();
      if (levelMenuItemStyles != null && levelMenuItemStyles.Count > 0)
        ((IStateManager)levelMenuItemStyles).TrackViewState();
      if (levelSelectedStyles != null && levelMenuItemStyles.Count > 0)
        ((IStateManager)levelSelectedStyles).TrackViewState();
      if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0)
        ((IStateManager)levelSubMenuStyles).TrackViewState();
      if (dynamicSelectedStyle != null)
        dynamicSelectedStyle.TrackViewState();
      if (staticMenuItemStyle != null)
        staticMenuItemStyle.TrackViewState ();
      if (staticMenuStyle != null)
        staticMenuStyle.TrackViewState ();
      if (staticSelectedStyle != null)
        staticSelectedStyle.TrackViewState();
      if (staticHoverStyle != null)
        staticHoverStyle.TrackViewState();
      if (dynamicHoverStyle != null)
        dynamicHoverStyle.TrackViewState();
    }

    protected override object SaveViewState()
    {
      object[] states = new object [14];
      states[0] = base.SaveViewState ();
      states[1] = dataBindings == null ? null : ((IStateManager)dataBindings).SaveViewState();
      states[2] = items == null ? null : ((IStateManager)items).SaveViewState();
      states[3] = dynamicMenuItemStyle == null ? null : dynamicMenuItemStyle.SaveViewState();
      states[4] = dynamicMenuStyle == null ? null : dynamicMenuStyle.SaveViewState();
      states[5] = levelMenuItemStyles == null ? null : ((IStateManager)levelMenuItemStyles).SaveViewState();
      states[6] = levelSelectedStyles == null ? null : ((IStateManager)levelSelectedStyles).SaveViewState();
      states[7] = dynamicSelectedStyle == null ? null : dynamicSelectedStyle.SaveViewState();
      states[8] = (staticMenuItemStyle == null ? null : staticMenuItemStyle.SaveViewState());
      states[9] = staticMenuStyle == null ? null : staticMenuStyle.SaveViewState();
      states[10] = staticSelectedStyle == null ? null : staticSelectedStyle.SaveViewState();
      states[11] = staticHoverStyle == null ? null : staticHoverStyle.SaveViewState();
      states[12] = dynamicHoverStyle == null ? null : dynamicHoverStyle.SaveViewState();
      states[13] = levelSubMenuStyles == null ? null : ((IStateManager)levelSubMenuStyles).SaveViewState();

      for (int i = states.Length - 1; i >= 0; i--) {
        if (states [i] != null)
          return states;
      }

      return null;
    }

    protected override void LoadViewState (object savedState)
    {
      if (savedState == null)
        return;

      object [] states = (object []) savedState;
      base.LoadViewState (states[0]);
      
      if (states[1] != null)
        ((IStateManager)DataBindings).LoadViewState(states[1]);
      if (states[2] != null)
        ((IStateManager)Items).LoadViewState(states[2]);
      if (states[3] != null)
        DynamicMenuItemStyle.LoadViewState (states[3]);
      if (states[4] != null)
        DynamicMenuStyle.LoadViewState (states[4]);
      if (states[5] != null)
        ((IStateManager)LevelMenuItemStyles).LoadViewState(states[5]);
      if (states[6] != null)
        ((IStateManager)LevelSelectedStyles).LoadViewState(states[6]);
      if (states[7] != null)
        DynamicSelectedStyle.LoadViewState (states[7]);
      if (states[8] != null)
        StaticMenuItemStyle.LoadViewState (states[8]);
      if (states[9] != null)
        StaticMenuStyle.LoadViewState (states[9]);
      if (states[10] != null)
        StaticSelectedStyle.LoadViewState (states[10]);
      if (states[11] != null)
        StaticHoverStyle.LoadViewState (states[11]);
      if (states[12] != null)
        DynamicHoverStyle.LoadViewState (states[12]);
      if (states[13] != null)
        ((IStateManager)LevelSubMenuStyles).LoadViewState(states[13]);
    }
    
    protected internal override void OnInit (EventArgs e)
    {
      Page.RegisterRequiresControlState (this);
      base.OnInit (e);
    }
    
    protected internal override void LoadControlState (object ob)
    {
      if (ob == null) return;
      object[] state = (object[]) ob;
      base.LoadControlState (state[0]);
      selectedItemPath = state[1] as string;
    }
    
    protected internal override object SaveControlState ()
    {
      object bstate = base.SaveControlState ();
      object mstate = selectedItemPath;
      
      if (bstate != null || mstate != null)
        return new object[] { bstate, mstate };
      else
        return null;
    }
    
    protected internal override void CreateChildControls ()
    {
      if (!IsBoundUsingDataSourceID && (DataSource == null)) {
        CreateChildControlsForItems ();
      }
      else {
        EnsureDataBound ();
      }
    }

    void CreateChildControlsForItems () {
      Controls.Clear ();
      // Check for HasChildViewState to avoid unnecessary calls to ClearChildViewState.
      if (HasChildViewState)
        ClearChildViewState ();
      _menuItemControls = new Hashtable ();
      CreateChildControlsForItems (Items);
      _requiresChildControlsDataBinding = true;
    }

    void CreateChildControlsForItems (MenuItemCollection items ) {
      foreach (MenuItem item in items) {
        bool isDynamicItem = IsDynamicItem (item);
        if (isDynamicItem && dynamicItemTemplate != null) {
          MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
          dynamicItemTemplate.InstantiateIn (cter);
          _menuItemControls [item] = cter;
          Controls.Add (cter);
        }
        else if (!isDynamicItem && staticItemTemplate != null) {
          MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
          staticItemTemplate.InstantiateIn (cter);
          _menuItemControls [item] = cter;
          Controls.Add (cter);
        }
        if (item.HasChildData)
          CreateChildControlsForItems (item.ChildItems);
      }
    }

    protected override void EnsureDataBound ()
    {
      base.EnsureDataBound ();
      
      EnsureChildControlsDataBound ();
    }

    void EnsureChildControlsDataBound () {
      if (!_requiresChildControlsDataBinding)
        return;
      DataBindChildren ();
      _requiresChildControlsDataBinding = false;
    }

    [MonoTODO ("Not implemented")]
    protected override IDictionary GetDesignModeState ()
    {
      throw new NotImplementedException ();
    }

    [MonoTODO ("Not implemented")]
    protected override void SetDesignModeState (IDictionary data)
    {
      throw new NotImplementedException ();
    }
        
    public override ControlCollection Controls {
      get { return base.Controls; }
    }
    
    public sealed override void DataBind ()
    {
      base.DataBind ();
    }
    
    protected override bool OnBubbleEvent (object source, EventArgs args)
    {
      if (!(args is CommandEventArgs))
        return false;

      MenuEventArgs menuArgs = args as MenuEventArgs;
      if (menuArgs != null && string.Equals (menuArgs.CommandName, MenuItemClickCommandName))
        OnMenuItemClick (menuArgs);
      return true;
    }

    protected override void OnDataBinding (EventArgs e)
    {
      EnsureChildControls ();
      base.OnDataBinding (e);
    }

    const string onPreRenderScript = "var {0} = new Object ();\n{0}.webForm = {1};\n{0}.disappearAfter = {2};\n{0}.vertical = {3};";
    
    protected internal override void OnPreRender (EventArgs e)
    {
      base.OnPreRender (e);
      
      if (!Page.ClientScript.IsClientScriptIncludeRegistered (typeof(Menu), "Menu.js")) {
        string url = Page.ClientScript.GetWebResourceUrl (typeof(Menu), "Menu.js");
        Page.ClientScript.RegisterClientScriptInclude (typeof(Menu), "Menu.js", url);
      }
      
      string cmenu = ClientID + "_data";
      string script = String.Format (onPreRenderScript,
                   cmenu,
                   Page.IsMultiForm ? Page.theForm : "window",
                   ClientScriptManager.GetScriptLiteral (DisappearAfter),
                   ClientScriptManager.GetScriptLiteral (Orientation == Orientation.Vertical));      

      if (DynamicHorizontalOffset != 0)
        script += String.Concat (cmenu, ".dho = ", ClientScriptManager.GetScriptLiteral (DynamicHorizontalOffset), ";\n");
      if (DynamicVerticalOffset != 0)
        script += String.Concat (cmenu, ".dvo = ", ClientScriptManager.GetScriptLiteral (DynamicVerticalOffset), ";\n");
      
      // The order in which styles are defined matters when more than one class
      // is assigned to an element
      RegisterStyle (PopOutBoxStyle);
      RegisterStyle (ControlStyle, ControlLinkStyle);
      
      if (staticMenuItemStyle != null)
        RegisterStyle (StaticMenuItemStyle, StaticMenuItemLinkStyle);

      if (staticMenuStyle != null)
        RegisterStyle (StaticMenuStyle);
      
      if (dynamicMenuItemStyle != null)
        RegisterStyle (DynamicMenuItemStyle, DynamicMenuItemLinkStyle);

      if (dynamicMenuStyle != null)
        RegisterStyle (DynamicMenuStyle);

      if (levelMenuItemStyles != null && levelMenuItemStyles.Count > 0) {
        levelMenuItemLinkStyles = new List<Style> (levelMenuItemStyles.Count);
        foreach (Style style in levelMenuItemStyles) {
          Style linkStyle = new Style ();
          levelMenuItemLinkStyles.Add (linkStyle);
          RegisterStyle (style, linkStyle);
        }
      }
    
      if (levelSubMenuStyles != null)
        foreach (Style style in levelSubMenuStyles)
          RegisterStyle (style);

      if (staticSelectedStyle != null)
        RegisterStyle (staticSelectedStyle, StaticSelectedLinkStyle);
      
      if (dynamicSelectedStyle != null)
        RegisterStyle (dynamicSelectedStyle, DynamicSelectedLinkStyle);

      if (levelSelectedStyles != null && levelSelectedStyles.Count > 0) {
        levelSelectedLinkStyles = new List<Style> (levelSelectedStyles.Count);
        foreach (Style style in levelSelectedStyles) {
          Style linkStyle = new Style ();
          levelSelectedLinkStyles.Add (linkStyle);
          RegisterStyle (style, linkStyle);
        }
      }
      
      if (staticHoverStyle != null) {
        if (Page.Header == null)
          throw new InvalidOperationException ("Using Menu.StaticHoverStyle requires Page.Header to be non-null (e.g. <head runat=\"server\" />).");
        RegisterStyle (staticHoverStyle, StaticHoverLinkStyle);
        script += string.Concat (cmenu, ".staticHover = ", ClientScriptManager.GetScriptLiteral (staticHoverStyle.RegisteredCssClass), ";\n");
        script += string.Concat (cmenu, ".staticLinkHover = ", ClientScriptManager.GetScriptLiteral (StaticHoverLinkStyle.RegisteredCssClass), ";\n");
      }
      
      if (dynamicHoverStyle != null) {
        if (Page.Header == null)
          throw new InvalidOperationException ("Using Menu.DynamicHoverStyle requires Page.Header to be non-null (e.g. <head runat=\"server\" />).");
        RegisterStyle (dynamicHoverStyle, DynamicHoverLinkStyle);
        script += string.Concat (cmenu, ".dynamicHover = ", ClientScriptManager.GetScriptLiteral (dynamicHoverStyle.RegisteredCssClass), ";\n");
        script += string.Concat (cmenu, ".dynamicLinkHover = ", ClientScriptManager.GetScriptLiteral (DynamicHoverLinkStyle.RegisteredCssClass), ";\n");
      }

      Page.ClientScript.RegisterWebFormClientScript ();
      Page.ClientScript.RegisterStartupScript (typeof(Menu), ClientID, script, true);

    }

    void InitializeDataBindings () {
      if (dataBindings != null && dataBindings.Count > 0) {
        bindings = new Hashtable ();
        foreach (MenuItemBinding bin in dataBindings) {
          string key = GetBindingKey (bin.DataMember, bin.Depth);
          bindings [key] = bin;
        }
      }
      else
        bindings = null;
    }

    string IncrementStyleClassName () {
      registeredStylesCounter++;
      return ClientID + "_" + registeredStylesCounter;
    }

    void RegisterStyle (Style baseStyle, Style linkStyle) {
      linkStyle.CopyTextStylesFrom (baseStyle);
      linkStyle.BorderStyle = BorderStyle.None;
      RegisterStyle (linkStyle);
      RegisterStyle (baseStyle);
    }

    void RegisterStyle (Style baseStyle)
    {
      if (Page.Header == null)
        return;
      string className = IncrementStyleClassName ();
      baseStyle.SetRegisteredCssClass (className);
      Page.Header.StyleSheet.CreateStyleRule (baseStyle, this, "." + className);
    }
    
    protected internal override void Render (HtmlTextWriter writer)
    {
      if (Items.Count > 0)
        base.Render (writer);
    }
    
    protected override void AddAttributesToRender (HtmlTextWriter writer)
    {
      writer.AddAttribute ("cellpadding", "0", false);
      writer.AddAttribute ("cellspacing", "0", false);
      writer.AddAttribute ("border", "0", false);
      if (Page.Header != null) {
        // styles are registered
        if (staticMenuStyle != null) {
          AddCssClass (ControlStyle, staticMenuStyle.CssClass);
          AddCssClass (ControlStyle, staticMenuStyle.RegisteredCssClass);
        }
        if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0) {
          AddCssClass (ControlStyle, levelSubMenuStyles [0].CssClass);
          AddCssClass (ControlStyle, levelSubMenuStyles [0].RegisteredCssClass);
        }
      }
      else {
        // styles are not registered
        if (staticMenuStyle != null){
          ControlStyle.CopyFrom (staticMenuStyle);
        }
        if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0) {
          ControlStyle.CopyFrom (levelSubMenuStyles [0]);
        }
      }
      base.AddAttributesToRender (writer);
    }

    void AddCssClass (Style style, string cssClass) {
      style.AddCssClass (cssClass);
    }
    
    public override void RenderBeginTag (HtmlTextWriter writer)
    {
      if (SkipLinkText != "") {
        System.Web.UI.HtmlControls.HtmlAnchor anchor = new System.Web.UI.HtmlControls.HtmlAnchor ();
        anchor.HRef = "#" + ClientID + "_SkipLink";

        Image img = new Image ();
        ClientScriptManager csm = new ClientScriptManager (null);
        img.ImageUrl = csm.GetWebResourceUrl (typeof (SiteMapPath), "transparent.gif");
        img.Attributes.Add ("height", "0");
        img.Attributes.Add ("width", "0");
        img.AlternateText = SkipLinkText;

        anchor.Controls.Add (img);
        anchor.Render (writer);
      }
      base.RenderBeginTag (writer);
    }
    
    public override void RenderEndTag (HtmlTextWriter writer)
    {
      base.RenderEndTag (writer);

      if (StaticDisplayLevels == 1 && MaximumDynamicDisplayLevels > 0)
        RenderDynamicMenu (writer, Items);

      if (SkipLinkText != "") {
        System.Web.UI.HtmlControls.HtmlAnchor anchor = new System.Web.UI.HtmlControls.HtmlAnchor ();
        anchor.ID = ClientID + "_SkipLink";
        anchor.Render (writer);
      }
    }
    
    protected internal override void RenderContents (HtmlTextWriter writer)
    {
      RenderMenuBody (writer, Items, Orientation == Orientation.Vertical, false, false);
    }

    void RenderDynamicMenu (HtmlTextWriter writer, MenuItemCollection items) {
      for (int n = 0; n < items.Count; n++) {
        if (DisplayChildren (items [n])) {
          RenderDynamicMenu (writer, items [n]);
          RenderDynamicMenu (writer, items [n].ChildItems);
        }
      }
    }
    
    MenuRenderHtmlTemplate _dynamicTemplate;
    MenuRenderHtmlTemplate GetDynamicMenuTemplate (MenuItem item)
    {
      if (_dynamicTemplate != null) 
        return _dynamicTemplate;

      _dynamicTemplate = new MenuRenderHtmlTemplate ();
      HtmlTextWriter writer = _dynamicTemplate.GetMenuTemplateWriter ();

      if (Page.Header != null) {
        writer.AddAttribute (HtmlTextWriterAttribute.Class, MenuRenderHtmlTemplate.GetMarker (0));
      }
      else {
        writer.AddAttribute (HtmlTextWriterAttribute.Style, MenuRenderHtmlTemplate.GetMarker (0));
      }

      writer.AddStyleAttribute ("visibility", "hidden");
      writer.AddStyleAttribute ("position", "absolute");
      writer.AddStyleAttribute ("z-index", "1");
      writer.AddStyleAttribute ("left", "0px");
      writer.AddStyleAttribute ("top", "0px");
      writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (1));
      writer.RenderBeginTag (HtmlTextWriterTag.Div);

      // Up button
      writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (2));
      writer.AddStyleAttribute ("display", "block");
      writer.AddStyleAttribute ("text-align", "center");
      writer.AddAttribute ("onmouseover", string.Concat ("Menu_OverScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (3), "','u')"));
      writer.AddAttribute ("onmouseout", string.Concat ("Menu_OutScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (4), "','u')")); 
      writer.RenderBeginTag (HtmlTextWriterTag.Div);
      
      writer.AddAttribute ("src", MenuRenderHtmlTemplate.GetMarker (5)); //src
      writer.AddAttribute ("alt", MenuRenderHtmlTemplate.GetMarker (6)); //ScrollUpText
      writer.RenderBeginTag (HtmlTextWriterTag.Img);
      writer.RenderEndTag ();  // IMG
      
      writer.RenderEndTag ();  // DIV scroll button
    
      writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (7));
      writer.RenderBeginTag (HtmlTextWriterTag.Div);
      writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (8));
      writer.RenderBeginTag (HtmlTextWriterTag.Div);
      
      // call of RenderMenu
      writer.Write (MenuRenderHtmlTemplate.GetMarker (9));
      
      writer.RenderEndTag ();  // DIV Content
      writer.RenderEndTag ();  // DIV Scroll container

      // Down button
      writer.AddAttribute ("id", MenuRenderHtmlTemplate.GetMarker (0));
      writer.AddStyleAttribute ("display", "block");
      writer.AddStyleAttribute ("text-align", "center");
      writer.AddAttribute ("onmouseover", string.Concat ("Menu_OverScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (1), "','d')"));
      writer.AddAttribute ("onmouseout", string.Concat ("Menu_OutScrollBtn ('", ClientID, "','", MenuRenderHtmlTemplate.GetMarker (2), "','d')")); 
      writer.RenderBeginTag (HtmlTextWriterTag.Div);
      
      writer.AddAttribute ("src", MenuRenderHtmlTemplate.GetMarker (3)); //src
      writer.AddAttribute ("alt", MenuRenderHtmlTemplate.GetMarker (4)); //ScrollDownText
      writer.RenderBeginTag (HtmlTextWriterTag.Img);
      writer.RenderEndTag ();  // IMG
      
      writer.RenderEndTag ();  // DIV scroll button
      
      writer.RenderEndTag ();  // DIV menu

      _dynamicTemplate.Parse ();
      return _dynamicTemplate;
    }

    void RenderDynamicMenu (HtmlTextWriter writer, MenuItem item)
    {
      _dynamicTemplate = GetDynamicMenuTemplate (item);

      string idPrefix = ClientID + "_" + item.Path;
      string [] param = new string [9];
      param [0] = GetCssMenuStyle (true, item.Depth + 1);
      param [1] = idPrefix + "s";
      param [2] = idPrefix + "cu";
      param [3] = item.Path;
      param [4] = item.Path;
      param [5] = ScrollUpImageUrl != "" ? ScrollUpImageUrl : Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_up.gif");
      param [6] = ScrollUpText;
      param [7] = idPrefix + "cb";
      param [8] = idPrefix + "cc";

      _dynamicTemplate.RenderTemplate (writer, param, 0, param.Length);

      RenderMenu (writer, item.ChildItems, true, true, item.Depth + 1, false);

      string [] param2 = new string [5];
      param2 [0] = idPrefix + "cd";
      param2 [1] = item.Path;
      param2 [2] = item.Path;
      param2 [3] = ScrollDownImageUrl != "" ? ScrollDownImageUrl : Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_down.gif");
      param2 [4] = ScrollDownText;

      _dynamicTemplate.RenderTemplate (writer, param2, param.Length + 1, param2.Length);

    }

    string GetCssMenuStyle (bool dynamic, int menuLevel)
    {
      if (Page.Header != null) {
        // styles are registered
        StringBuilder sb = new StringBuilder ();

        if (!dynamic && staticMenuStyle != null) {
          sb.Append (staticMenuStyle.CssClass);
          sb.Append (' ');
          sb.Append (staticMenuStyle.RegisteredCssClass);
        }
        if (dynamic && dynamicMenuStyle != null) {
          sb.Append (PopOutBoxStyle.RegisteredCssClass);
          sb.Append (' ');
          sb.Append (dynamicMenuStyle.CssClass);
          sb.Append (' ');
          sb.Append (dynamicMenuStyle.RegisteredCssClass);
        }
        if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
          sb.Append (levelSubMenuStyles [menuLevel].CssClass);
          sb.Append (' ');
          sb.Append (levelSubMenuStyles [menuLevel].RegisteredCssClass); 
        }
        return sb.ToString ();
      }
      else {
        // styles are not registered
        SubMenuStyle style = new SubMenuStyle ();

        if (!dynamic && staticMenuStyle != null) {
          style.CopyFrom (staticMenuStyle);
        }
        if (dynamic && dynamicMenuStyle != null) {
          style.CopyFrom (PopOutBoxStyle);
          style.CopyFrom (dynamicMenuStyle);
        }
        if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
          style.CopyFrom (levelSubMenuStyles [menuLevel]);
        }
        return style.GetStyleAttributes (null).Value;
      }
    }

    void RenderMenuBeginTagAttributes (HtmlTextWriter writer, bool dynamic, int menuLevel) {
      writer.AddAttribute ("cellpadding", "0", false);
      writer.AddAttribute ("cellspacing", "0", false);
      writer.AddAttribute ("border", "0", false);

      if (!dynamic) {
        SubMenuStyle style = new SubMenuStyle ();
        FillMenuStyle (dynamic, menuLevel, style);
        style.AddAttributesToRender (writer);
      }
    }

    void FillMenuStyle (bool dynamic, int menuLevel, SubMenuStyle style) {
      if (Page.Header != null) {
        // styles are registered
        if (!dynamic && staticMenuStyle != null) {
          AddCssClass (style, staticMenuStyle.CssClass);
          AddCssClass (style, staticMenuStyle.RegisteredCssClass);
        }
        if (dynamic && dynamicMenuStyle != null) {
          AddCssClass (style, dynamicMenuStyle.CssClass);
          AddCssClass (style, dynamicMenuStyle.RegisteredCssClass);
        }
        if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
          AddCssClass (style, levelSubMenuStyles [menuLevel].CssClass);
          AddCssClass (style, levelSubMenuStyles [menuLevel].RegisteredCssClass);
        }
      }
      else {
        // styles are not registered
        if (!dynamic && staticMenuStyle != null) {
          style.CopyFrom (staticMenuStyle);
        }
        if (dynamic && dynamicMenuStyle != null) {
          style.CopyFrom (dynamicMenuStyle);
        }
        if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
          style.CopyFrom (levelSubMenuStyles [menuLevel]);
        }
      }
    }

    void RenderMenu (HtmlTextWriter writer, MenuItemCollection items, bool vertical, bool dynamic, int menuLevel, bool notLast)
    {
      RenderMenuBeginTag (writer, dynamic, menuLevel);
      RenderMenuBody (writer, items, vertical, dynamic, notLast);
      RenderMenuEndTag (writer);
    }
    
    void RenderMenuBeginTag (HtmlTextWriter writer, bool dynamic, int menuLevel)
    {
      RenderMenuBeginTagAttributes (writer, dynamic, menuLevel);
      writer.RenderBeginTag (HtmlTextWriterTag.Table);
    }
    
    void RenderMenuEndTag (HtmlTextWriter writer)
    {
      writer.RenderEndTag ();
    }

    void RenderMenuBody (HtmlTextWriter writer, MenuItemCollection items, bool vertical, bool dynamic, bool notLast) {
      if (!vertical)
        writer.RenderBeginTag (HtmlTextWriterTag.Tr);

      int count = items.Count;
      for (int n = 0; n < count; n++) {
        MenuItem item = items [n];
        Adapters.MenuAdapter adapter = Adapter as Adapters.MenuAdapter;
        if (adapter != null)
          adapter.RenderItem (writer, item, n);
        else
          RenderMenuItem (writer, item, (n + 1 == count) ? notLast : true, n == 0);
      }

      if (!vertical)
        writer.RenderEndTag ();  // TR
    }

    void RenderMenuItemSpacing (HtmlTextWriter writer, Unit itemSpacing, bool vertical) {
      if (vertical) {
        writer.AddStyleAttribute ("height", itemSpacing.ToString ());
        writer.RenderBeginTag (HtmlTextWriterTag.Tr);
        writer.RenderBeginTag (HtmlTextWriterTag.Td);
        writer.RenderEndTag ();
        writer.RenderEndTag ();
      }
      else {
        writer.AddStyleAttribute ("width", itemSpacing.ToString ());
        writer.RenderBeginTag (HtmlTextWriterTag.Td);
        writer.RenderEndTag ();
      }
    }
    
    bool IsDynamicItem (MenuItem item) {
      return item.Depth + 1 > StaticDisplayLevels;
    }

    bool DisplayChildren (MenuItem item) {
      return (item.Depth + 1 < StaticDisplayLevels + MaximumDynamicDisplayLevels) && item.ChildItems.Count > 0;
    }
    
    internal void RenderItem (HtmlTextWriter writer, MenuItem item, int position) {
      // notLast should be true if item or any of its ancestors is not a
      // last child.
      bool notLast = false;
      MenuItem parent;
      MenuItem child = item;      
      while (null != (parent = child.Parent)) {
        if (child.Index != parent.ChildItems.Count - 1) {
          notLast = true;
          break;
        }
        child = parent;
      }
      
      RenderMenuItem (writer, item, notLast, position == 0);
    }
    
    void RenderMenuItem (HtmlTextWriter writer, MenuItem item, bool notLast, bool isFirst) {
      bool displayChildren = DisplayChildren (item);
      bool dynamicChildren = displayChildren && (item.Depth + 1 >= StaticDisplayLevels);
      bool isDynamicItem = IsDynamicItem (item);
      bool vertical = (Orientation == Orientation.Vertical) || isDynamicItem;
      
      Unit itemSpacing = GetItemSpacing (item, isDynamicItem);

      if (itemSpacing != Unit.Empty && (item.Depth > 0 || !isFirst))
        RenderMenuItemSpacing (writer, itemSpacing, vertical);

      if(!String.IsNullOrEmpty(item.ToolTip))
        writer.AddAttribute (HtmlTextWriterAttribute.Title, item.ToolTip);
      if (vertical)
        writer.RenderBeginTag (HtmlTextWriterTag.Tr);

      string parentId = isDynamicItem ? "'" + item.Parent.Path + "'" : "null";
      if (dynamicChildren) {
        writer.AddAttribute ("onmouseover",
                 "javascript:Menu_OverItem ('" + ClientID + "','" + item.Path + "'," + parentId + ")");
        writer.AddAttribute ("onmouseout",
                 "javascript:Menu_OutItem ('" + ClientID + "','" + item.Path + "')");
      } else if (isDynamicItem) {
        writer.AddAttribute ("onmouseover",
                 "javascript:Menu_OverDynamicLeafItem ('" + ClientID + "','" + item.Path + "'," + parentId + ")");
        writer.AddAttribute ("onmouseout",
                 "javascript:Menu_OutItem ('" + ClientID + "','" + item.Path + "'," + parentId + ")");
      } else {
        writer.AddAttribute ("onmouseover",
                 "javascript:Menu_OverStaticLeafItem ('" + ClientID + "','" + item.Path + "')");
        writer.AddAttribute ("onmouseout",
                 "javascript:Menu_OutItem ('" + ClientID + "','" + item.Path + "')");
      }

      writer.RenderBeginTag (HtmlTextWriterTag.Td);

      // Top separator image

      if (isDynamicItem && DynamicTopSeparatorImageUrl != "") {
        writer.AddAttribute ("src", ResolveClientUrl (DynamicTopSeparatorImageUrl));
        writer.RenderBeginTag (HtmlTextWriterTag.Img);
        writer.RenderEndTag ();  // IMG
      }
      else if (!isDynamicItem && StaticTopSeparatorImageUrl != "") {
        writer.AddAttribute ("src", ResolveClientUrl (StaticTopSeparatorImageUrl));
        writer.RenderBeginTag (HtmlTextWriterTag.Img);
        writer.RenderEndTag ();  // IMG
      }

      // Menu item box
      
      MenuItemStyle style = new MenuItemStyle ();
      if (Page.Header != null) {
        // styles are registered
        if (!isDynamicItem && staticMenuItemStyle != null) {
          AddCssClass (style, staticMenuItemStyle.CssClass);
          AddCssClass (style, staticMenuItemStyle.RegisteredCssClass);
        }
        if (isDynamicItem && dynamicMenuItemStyle != null) {
          AddCssClass (style, dynamicMenuItemStyle.CssClass);
          AddCssClass (style, dynamicMenuItemStyle.RegisteredCssClass);
        }
        if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
          AddCssClass (style, levelMenuItemStyles [item.Depth].CssClass);
          AddCssClass (style, levelMenuItemStyles [item.Depth].RegisteredCssClass);
        }
        if (item == SelectedItem) {
          if (!isDynamicItem && staticSelectedStyle != null) {
            AddCssClass (style, staticSelectedStyle.CssClass);
            AddCssClass (style, staticSelectedStyle.RegisteredCssClass);
          }
          if (isDynamicItem && dynamicSelectedStyle != null) {
            AddCssClass (style, dynamicSelectedStyle.CssClass);
            AddCssClass (style, dynamicSelectedStyle.RegisteredCssClass);
          }
          if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
            AddCssClass (style, levelSelectedStyles [item.Depth].CssClass);
            AddCssClass (style, levelSelectedStyles [item.Depth].RegisteredCssClass);
          }
        }
      }
      else {
        // styles are not registered
        if (!isDynamicItem && staticMenuItemStyle != null) {
          style.CopyFrom (staticMenuItemStyle);
        }
        if (isDynamicItem && dynamicMenuItemStyle != null) {
          style.CopyFrom (dynamicMenuItemStyle);
        }
        if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
          style.CopyFrom (levelMenuItemStyles [item.Depth]);
        }
        if (item == SelectedItem) {
          if (!isDynamicItem && staticSelectedStyle != null) {
            style.CopyFrom (staticSelectedStyle);
          }
          if (isDynamicItem && dynamicSelectedStyle != null) {
            style.CopyFrom (dynamicSelectedStyle);
          }
          if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
            style.CopyFrom (levelSelectedStyles [item.Depth]);
          }
        }
      }
      style.AddAttributesToRender (writer);

      writer.AddAttribute ("id", GetItemClientId (item, "i"));

      writer.AddAttribute ("cellpadding", "0", false);
      writer.AddAttribute ("cellspacing", "0", false);
      writer.AddAttribute ("border", "0", false);
      writer.AddAttribute ("width", "100%", false);
      writer.RenderBeginTag (HtmlTextWriterTag.Table);
      writer.RenderBeginTag (HtmlTextWriterTag.Tr);

      // Menu item text

      if (vertical)
        writer.AddStyleAttribute (HtmlTextWriterStyle.Width, "100%");
      if (!ItemWrap)
        writer.AddStyleAttribute ("white-space", "nowrap");
      writer.RenderBeginTag (HtmlTextWriterTag.Td);

      RenderItemHref (writer, item);
      
      Style linkStyle = new Style ();
      if (Page.Header != null) {
        // styles are registered
        AddCssClass (linkStyle, ControlLinkStyle.RegisteredCssClass);

        if (!isDynamicItem && staticMenuItemStyle != null) {
          AddCssClass (linkStyle, staticMenuItemStyle.CssClass);
          AddCssClass (linkStyle, staticMenuItemLinkStyle.RegisteredCssClass);
        }
        if (isDynamicItem && dynamicMenuItemStyle != null) {
          AddCssClass (linkStyle, dynamicMenuItemStyle.CssClass);
          AddCssClass (linkStyle, dynamicMenuItemLinkStyle.RegisteredCssClass);
        }
        if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
          AddCssClass (linkStyle, levelMenuItemStyles [item.Depth].CssClass);
          AddCssClass (linkStyle, levelMenuItemLinkStyles [item.Depth].RegisteredCssClass);
        }
        if (item == SelectedItem) {
          if (!isDynamicItem && staticSelectedStyle != null) {
            AddCssClass (linkStyle, staticSelectedStyle.CssClass);
            AddCssClass (linkStyle, staticSelectedLinkStyle.RegisteredCssClass);
          }
          if (isDynamicItem && dynamicSelectedStyle != null) {
            AddCssClass (linkStyle, dynamicSelectedStyle.CssClass);
            AddCssClass (linkStyle, dynamicSelectedLinkStyle.RegisteredCssClass);
          }
          if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
            AddCssClass (linkStyle, levelSelectedStyles [item.Depth].CssClass);
            AddCssClass (linkStyle, levelSelectedLinkStyles [item.Depth].RegisteredCssClass);
          }
        }
      }
      else {
        // styles are not registered
        linkStyle.CopyFrom (ControlLinkStyle);

        if (!isDynamicItem && staticMenuItemStyle != null) {
          linkStyle.CopyFrom (staticMenuItemLinkStyle);
        }
        if (isDynamicItem && dynamicMenuItemStyle != null) {
          linkStyle.CopyFrom (dynamicMenuItemLinkStyle);
        }
        if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
          linkStyle.CopyFrom (levelMenuItemLinkStyles [item.Depth]);
        }
        if (item == SelectedItem) {
          if (!isDynamicItem && staticSelectedStyle != null) {
            linkStyle.CopyFrom (staticSelectedLinkStyle);
          }
          if (isDynamicItem && dynamicSelectedStyle != null) {
            linkStyle.CopyFrom (dynamicSelectedLinkStyle);
          }
          if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
            linkStyle.CopyFrom (levelSelectedLinkStyles [item.Depth]);
          }
        }

        linkStyle.AlwaysRenderTextDecoration = true;
      }
      linkStyle.AddAttributesToRender (writer);

      writer.AddAttribute ("id", GetItemClientId (item, "l"));
      
      if (item.Depth > 0 && !isDynamicItem) {
        Unit indent = new Unit (StaticSubMenuIndent.Value * item.Depth, StaticSubMenuIndent.Type);
        writer.AddStyleAttribute ("margin-left", indent.ToString ());
      }
      writer.RenderBeginTag (HtmlTextWriterTag.A);
      RenderItemContent (writer, item, isDynamicItem);
      writer.RenderEndTag ();  // A

      writer.RenderEndTag ();  // TD

      // Popup image

      if (dynamicChildren) {
        string popOutImage = GetPopOutImage (item, isDynamicItem);
        if (popOutImage != null) {
          writer.RenderBeginTag (HtmlTextWriterTag.Td);
          writer.AddAttribute ("src", ResolveClientUrl (popOutImage));
          writer.AddAttribute ("border", "0");
          string toolTip = String.Format (isDynamicItem ? DynamicPopOutImageTextFormatString : StaticPopOutImageTextFormatString, item.Text);
          writer.AddAttribute (HtmlTextWriterAttribute.Alt, toolTip);
          writer.RenderBeginTag (HtmlTextWriterTag.Img);
          writer.RenderEndTag ();  // IMG
          writer.RenderEndTag ();  // TD
        }
      }

      writer.RenderEndTag ();  // TR
      writer.RenderEndTag ();  // TABLE
      
      writer.RenderEndTag ();  // TD

      if (!vertical && itemSpacing == Unit.Empty && (notLast || (displayChildren && !dynamicChildren))) {
        writer.AddStyleAttribute ("width", "3px");
        writer.RenderBeginTag (HtmlTextWriterTag.Td);
        writer.RenderEndTag ();
      }
      
      // Bottom separator image
      string separatorImg = item.SeparatorImageUrl;
      if (separatorImg.Length == 0) {
        if (isDynamicItem)
          separatorImg = DynamicBottomSeparatorImageUrl;
        else
          separatorImg = StaticBottomSeparatorImageUrl;
      }
      if (separatorImg.Length > 0) {
        if (!vertical)
          writer.RenderBeginTag (HtmlTextWriterTag.Td);
        writer.AddAttribute ("src", ResolveClientUrl (separatorImg));
        writer.RenderBeginTag (HtmlTextWriterTag.Img);
        writer.RenderEndTag ();  // IMG
        if (!vertical)
          writer.RenderEndTag (); // TD
      }

      if (vertical)
        writer.RenderEndTag ();  // TR

      if (itemSpacing != Unit.Empty)
        RenderMenuItemSpacing (writer, itemSpacing, vertical);

      // Submenu

      if (displayChildren && !dynamicChildren) {
        if (vertical)
          writer.RenderBeginTag (HtmlTextWriterTag.Tr);
        writer.RenderBeginTag (HtmlTextWriterTag.Td);
        writer.AddAttribute ("width", "100%");
        RenderMenu (writer, item.ChildItems, Orientation == Orientation.Vertical, false, item.Depth + 1, notLast);
        if (item.Depth + 2 == StaticDisplayLevels)
          RenderDynamicMenu (writer, item.ChildItems);
        writer.RenderEndTag ();  // TD
        if (vertical)
          writer.RenderEndTag ();  // TR
      }

    }

    void RenderItemContent (HtmlTextWriter writer, MenuItem item, bool isDynamicItem) {
      if (_menuItemControls!=null && _menuItemControls [item] != null) {
        ((Control) _menuItemControls [item]).Render (writer);
      }
      else {

        if (!String.IsNullOrEmpty (item.ImageUrl)) {
          writer.AddAttribute (HtmlTextWriterAttribute.Src, ResolveClientUrl (item.ImageUrl));
          writer.AddAttribute (HtmlTextWriterAttribute.Alt, item.ToolTip);
          writer.AddStyleAttribute (HtmlTextWriterStyle.BorderStyle, "none");
          writer.AddStyleAttribute (HtmlTextWriterStyle.VerticalAlign, "middle");
          writer.RenderBeginTag (HtmlTextWriterTag.Img);
          writer.RenderEndTag ();  // IMG
        }

        if (isDynamicItem && DynamicItemFormatString.Length > 0) {
          writer.Write (String.Format (DynamicItemFormatString, item.Text));
        }
        else if (!isDynamicItem && StaticItemFormatString.Length > 0) {
          writer.Write (String.Format (StaticItemFormatString, item.Text));
        }
        else {
          writer.Write (item.Text);
        }
      }
    }
      
    Unit GetItemSpacing (MenuItem item, bool dynamic)
    {
      Unit itemSpacing = Unit.Empty;
      
      if (item.Selected) {
        if (levelSelectedStyles != null && item.Depth < levelSelectedStyles.Count) {
          itemSpacing = levelSelectedStyles [item.Depth].ItemSpacing;
          if (itemSpacing != Unit.Empty) return itemSpacing;
        }

        if (dynamic && dynamicSelectedStyle != null)
          itemSpacing = dynamicSelectedStyle.ItemSpacing;
        else if (!dynamic && staticSelectedStyle != null)
          itemSpacing = staticSelectedStyle.ItemSpacing;
        if (itemSpacing != Unit.Empty)
          return itemSpacing;
      }
      
      if (levelMenuItemStyles != null && item.Depth < levelMenuItemStyles.Count) {
        itemSpacing = levelMenuItemStyles [item.Depth].ItemSpacing;
        if (itemSpacing != Unit.Empty) return itemSpacing;
      }

      if (dynamic && dynamicMenuItemStyle != null)
        return dynamicMenuItemStyle.ItemSpacing;
      else if (!dynamic && staticMenuItemStyle != null)
        return staticMenuItemStyle.ItemSpacing;
      else
        return Unit.Empty;
    }
    
    string GetPopOutImage (MenuItem item, bool isDynamicItem)
    {
      if (item.PopOutImageUrl != "")
        return item.PopOutImageUrl;

      if (isDynamicItem) {
        if (DynamicPopOutImageUrl != "")
          return DynamicPopOutImageUrl;
        if (DynamicEnableDefaultPopOutImage)
          return Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_plus.gif");
      } else {
        if (StaticPopOutImageUrl != "")
          return StaticPopOutImageUrl;
        if (StaticEnableDefaultPopOutImage)
          return Page.ClientScript.GetWebResourceUrl (typeof (Menu), "arrow_plus.gif");
      }
      return null;
    }
      
    void RenderItemHref (HtmlTextWriter writer, MenuItem item)
    {
      if (!item.BranchEnabled) {
        writer.AddAttribute ("disabled", "true", false);
      }
      else if (!item.Selectable) {
        writer.AddAttribute ("href", "#", false);
        writer.AddStyleAttribute ("cursor", "text");
      }
      else if (item.NavigateUrl != "") {
        string target = item.Target != "" ? item.Target : Target;
#if TARGET_J2EE
        string navUrl = ResolveClientUrl (item.NavigateUrl, String.Compare (target, "_blank", StringComparison.InvariantCultureIgnoreCase) != 0);
#else
        string navUrl = ResolveClientUrl (item.NavigateUrl);
#endif
        writer.AddAttribute ("href", navUrl);
        if (target != "")
          writer.AddAttribute ("target", target);
      }
      else {
        writer.AddAttribute ("href", GetClientEvent (item));
      }

    }
    
    string GetItemClientId (MenuItem item, string sufix)
    {
      return ClientID + "_" + item.Path + sufix;
    }
    
    string GetClientEvent (MenuItem item)
    {
      return Page.ClientScript.GetPostBackClientHyperlink (this, item.Path, true);
    }

    class MenuTemplateWriter : TextWriter
    {
      char [] _buffer;
      int _ptr = 0;
      
      public MenuTemplateWriter (char [] buffer)
      {
        _buffer = buffer;
      }

      public override Encoding Encoding
      {
        get { return Encoding.Unicode; }
      }

      public override void Write (char value)
      {
        if (_ptr == _buffer.Length)
          EnsureCapacity ();
        
        _buffer [_ptr++] = value;
      }

      public override void Write (string value)
      {
        if (value == null)
          return;

        if (_ptr + value.Length >= _buffer.Length)
          EnsureCapacity ();

        for (int i = 0; i < value.Length; i++)
          _buffer [_ptr++] = value [i];
      }

      void EnsureCapacity ()
      {
        char [] tmpBuffer = new char [_buffer.Length * 2];
        Array.Copy (_buffer, tmpBuffer, _buffer.Length);

        _buffer = tmpBuffer;
      }
    }

    class MenuRenderHtmlTemplate
    {
      public const string Marker = "\u093a\u093b\u0971";
      char [] _templateHtml;

      MenuTemplateWriter _templateWriter;
      ArrayList idxs = new ArrayList (32);

      public MenuRenderHtmlTemplate ()
      {
        _templateHtml = new char [1024];
        _templateWriter = new MenuTemplateWriter (_templateHtml);
      }

      public static string GetMarker (int num)
      {
        char charNum = (char) ((int) '\u0971' + num);
        return string.Concat (Marker, charNum);
      }

      public HtmlTextWriter GetMenuTemplateWriter()
      {
        return new HtmlTextWriter (_templateWriter);
      }

      public void Parse ()
      {
        int mpos = 0;
        for (int i = 0; i < _templateHtml.Length; i++) {
          if (_templateHtml [i] == '\0') {
            idxs.Add (i);
            break;
          }

          if (_templateHtml [i] != Marker [mpos]) {
            mpos = 0;
            continue;
          }

          mpos++;
          if (mpos == Marker.Length) {
            mpos = 0;
            idxs.Add (i - Marker.Length + 1);
          }
        }
      }

      public void RenderTemplate (HtmlTextWriter writer, string [] dynamicParts, int start, int count)
      {
        if (idxs.Count == 0)
          return;

        int partStart = 0;
        int partEnd = (start == 0) ? -Marker.Length - 1 : (int) idxs [start - 1];
        int di = 0;

        int i = start;
        int total = start + count;
        for (; i < total; i++) {

          partStart = partEnd + Marker.Length + 1;
          partEnd = (int) idxs [i];
          
          // write static part
          writer.Write (_templateHtml, partStart, partEnd - partStart);

          // write synamic part
          di = (int) _templateHtml [partEnd + Marker.Length] - 0x971;
          writer.Write (dynamicParts [di]);
        }

        partStart = partEnd + Marker.Length + 1;
        partEnd = (int) idxs [i];

        writer.Write (_templateHtml, partStart, partEnd - partStart);
      }
    
    }
  }
}

#endif
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.