C# asp.net中来自数据库的菜单控件
我的母版页中有一个菜单控件。菜单的名称和相应的url来自数据库。如果菜单有子菜单,它也会正确显示。 但是如果子菜单有子菜单,问题就会出现。 我的数据库表有4列 MenuId | | MenuName | | | ParentId | | URL 代码是C# asp.net中来自数据库的菜单控件,c#,asp.net,sql,C#,Asp.net,Sql,我的母版页中有一个菜单控件。菜单的名称和相应的url来自数据库。如果菜单有子菜单,它也会正确显示。 但是如果子菜单有子菜单,问题就会出现。 我的数据库表有4列 MenuId | | MenuName | | | ParentId | | URL 代码是 private void getMenu() { DataSet ds = new DataSet(); DataTable dt = new DataTable(); ds = objSec.ShowMenu(
private void getMenu()
{
DataSet ds = new DataSet();
DataTable dt = new DataTable();
ds = objSec.ShowMenu(s_UserId);
dt = ds.Tables[0];
DataRow[] drowpar = dt.Select("ParentID=" + 0);
foreach (DataRow dr in drowpar)
{
menuBar.Items.Add(new MenuItem(dr["MenuName"].ToString(), dr["MenuID"].ToString(),
"", dr["URL"].ToString()));
}
foreach (DataRow dr in dt.Select("ParentID >" + 0))
{
try
{
MenuItem mnu = new MenuItem(dr["MenuName"].ToString(), dr["MenuID"].ToString(),
"", dr["URL"].ToString());
menuBar.FindItem(dr["ParentID"].ToString()).ChildItems.Add(mnu);
}
catch (Exception ex)
{
}
}
}
如果表中的子项位于其父项之前,则示例中的方法可能会导致不正确的结果。此外,空的catch块可能会隐藏任何错误。因此,我推荐另一种方法 您也可以使用递归来填充控件,而不是循环表。这将删除重复代码的数量:
private void getMenu()
{
DataSet ds = objSec.ShowMenu(s_UserId);
DataTable dt = ds.Tables[0];
AddMenuItems(dt, 0, menu.Items);
}
private void AddMenuItems(DataTable dt, int parentId, MenuItemCollection items)
{
DataRow[] rows = dt.Select("ParentID=" + parentId.ToString());
foreach(var dr in rows)
{
var id = (int) dr["MenuID"];
var menuItem = new MenuItem(dr["MenuName"].ToString(), id.ToString(),
"", dr["URL"].ToString());
items.Add(menuItem);
// Add subitems
AddMenuItems(dt, id, menuItem.ChildItems);
}
}
该示例首先调用顶级项ParentID=0的AddMenuItems方法。添加每个项后,通过再次调用AddMenuItems方法添加其子项,因此术语为recursive,提供顶级项的id作为父项。对于每个第二级子级,将再次调用该方法,以此类推