asp.net databound menu multilevel

后端 未结 1 857
走了就别回头了
走了就别回头了 2021-02-11 08:30

I am currently using an asp.net menu control to load from a table parent/child items. The problem I am having is that if the child has another child. My code is kindof static

相关标签:
1条回答
  • 2021-02-11 08:50

    Here's one way you could do it.

    • Represent parent/child relationship in your table with an adjacency list
    • Map that adjacency list into a tree structure
    • Convert that tree structure into your structure of menu items

    Maybe you could skip that middle step and map the adjacency list straight to a tree of MenuItems, maybe with some extension methods on MenuItem.

    But anyway...

    Default.aspx

    <%@ Page Language="C#" Inherits="MenuTreeDemo.Default" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html>
    <head runat="server">
        <title>Default</title>
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:Menu ID="MyMenu" runat="server" StaticDisplayLevels="3" />
        </form>
    </body>
    </html>
    

    Default.aspx.cs

    using System;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Data;
    using System.Collections.Generic;
    
    namespace MenuTreeDemo
    {
        public partial class Default : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)    
            {
                if (!IsPostBack)
                {
                    MenuNode root = ConvertTableToTree(GetTreeTable());
                    foreach (MenuNode topLevelNode in root.Children)
                    {
                        MyMenu.Items.Add(topLevelNode.ToMenuItem()); // Visits all nodes in the tree.
                    }
                }
            }
    
    
            // The menu tree as an adjacency list in a table. 
            static DataTable GetTreeTable()
            {
                DataTable table = new DataTable();
                table.Columns.Add("Id", typeof(int));
                table.Columns.Add("Description", typeof(string));
                table.Columns.Add("Url", typeof(string));
                table.Columns.Add("ParentId", typeof(int));
    
                table.Rows.Add(1, "TopMenu1", "/foo.html", 0);
                table.Rows.Add(2, "SubMenu1.1", "/baz.html", 1);
                table.Rows.Add(3, "SubMenu1.2", "/barry.html", 1);
                table.Rows.Add(4, "SubMenu1.2.1", "/skeet.html", 3);
                table.Rows.Add(5, "TopMenu2", "/bar.html", 0);
                table.Rows.Add(6, "TopMenu3", "/bar.html", 0);
                table.Rows.Add(7, "SubMenu3.1", "/ack.html", 6);
    
                return table;
            }
    
    
            // See e.g. http://stackoverflow.com/questions/2654627/most-efficient-way-of-creating-tree-from-adjacency-list
            // Assuming table is ordered.
            static MenuNode ConvertTableToTree(DataTable table)
            {
                var map = new Dictionary<int, MenuNode>();
                map[0] = new MenuNode() { Id = 0 }; // root node
    
                foreach (DataRow row in table.Rows)
                {
                    int nodeId = int.Parse(row["Id"].ToString());
                    int parentId = int.Parse(row["ParentId"].ToString());
    
                    MenuNode newNode = MenuNodeFromDataRow(row);
    
                    map[parentId].Children.Add(newNode);
                    map[nodeId] = newNode;
                }
    
                return map[0]; // root node
            }
    
    
            static MenuNode MenuNodeFromDataRow(DataRow row)
            {
                int nodeId = int.Parse(row["Id"].ToString());
                int parentId = int.Parse(row["ParentId"].ToString());
                string description = row["Description"].ToString();
                string url = row["Url"].ToString();
    
                return new MenuNode() { Id=nodeId, ParentId=parentId, Description=description, Url=url };
            }
        }
    }
    

    MenuNode.cs

    using System;
    using System.Collections.Generic;
    using System.Web.UI.WebControls;
    
    namespace MenuTreeDemo
    {
        public class MenuNode
        {
            public int Id { get; set; }
            public int ParentId { get; set; }
            public string Description { get; set; }
            public string Url { get; set; }
            public List<MenuNode> Children { get; set; }
    
    
            public MenuNode ()
            {
                Children = new List<MenuNode>();
            }
    
    
            // Will visit all descendants and turn them into menu items.
            public MenuItem ToMenuItem()
            {
                MenuItem item = new MenuItem(Description) { NavigateUrl=Url };
                foreach (MenuNode child in Children)
                {
                    item.ChildItems.Add(child.ToMenuItem());
                }
    
                return item;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题