asp.net数据绑定菜单多级

我目前正在使用asp.net菜单控件从表父/子项加载。 我遇到的问题是,如果孩子有另一个孩子。 从这个意义上说,我的代码是静态的,我似乎无法找到更好或“更”的方法。 我已经看到sitemap作为数据源,但我不需要站点地图,并且觉得这对我需要实现的东西来说太过分了。

foreach (ClassName option in list) { MenuItem module = new MenuItem(option.Description.ToLower(), "", "", option.Url + "?option=" + option.Optionid); module.Selectable = true; navigation.Items.Add(module); //this is my second level foreach (ClassName child in listfromparent(option.Optionid)) { MenuItem childmenu = new MenuItem(child.Description.ToLower(), "", "", child.Url + "?option=" + child.Optionid); module.ChildItems.Add(childmenu); } } 

正如你所看到的那样有效但是有2个级别:(当然我可以在孩子里面放另一个孩子级别来创建第3级但是如果有第4个,第5个怎么办?所以这就是为什么我需要它自己做。我注意到了treeview有人口,但显然菜单没有。提前谢谢。

这是你可以做到的一种方式。

  • 使用邻接列表表示表中的父/子关系
  • 将邻接列表映射到树结构中
  • 将该树结构转换为菜单项的结构

也许你可以跳过那个中间步骤并将邻接列表直接映射到MenuItems树,可能在MenuItem上有一些扩展方法。

但无论如何…

Default.aspx的

 <%@ Page Language="C#" Inherits="MenuTreeDemo.Default" %>    Default   

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 eg 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(); 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 Children { get; set; } public MenuNode () { Children = new List(); } // 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; } } }