在asp.net中从数据库创建动态菜单和子菜单

时间:2012-10-25 10:21:46

标签: asp.net master-pages

我想从数据库动态显示菜单。但是我的菜单项显示但是当我以前点击菜单时,子菜单没有显示。请告诉我错误在哪里

我的代码是

protected void Page_Load(object sender, EventArgs e)
{
    if(!IsPostBack)
    { GetMenuData(); }
}
private void GetMenuData()
{
    DataTable table = new DataTable();
    SqlConnection conn = new SqlConnection(@"Data Source=ST015\SQLEXPRESS;Initial Catalog=MyData;Integrated Security=True");
    string sql = "select menuId,Menuname,MenuDescription,ParentMenuid,MenuUrl from Categories";
    SqlCommand cmd = new SqlCommand(sql, conn);
    SqlDataAdapter da = new SqlDataAdapter(cmd);
    da.Fill(table);
    DataView view = new DataView(table);
    view.RowFilter = "ParentMenuId is NULL";
    foreach (DataRowView row in view)
    {
        MenuItem menuItem = new MenuItem(row["MenuName"].ToString(),
            row["MenuId"].ToString());
        menuItem.NavigateUrl = row["MenuUrl"].ToString();
        Menu1.Items.Add(menuItem);
        AddChildItems(table, menuItem);
    }
}
private void AddChildItems(DataTable table, MenuItem menuItem)
{
    DataView viewItem = new DataView(table);
    viewItem.RowFilter = "ParentMenuId=" + menuItem.Value;
    foreach (DataRowView childView in viewItem)
    {
        MenuItem childItem = new MenuItem(childView["MenuName"].ToString(),
            childView["MenuId"].ToString());
        childItem.NavigateUrl = childView["MenuUrl"].ToString();
        menuItem.ChildItems.Add(childItem);
        AddChildItems(table, childItem);
    }
}

3 个答案:

答案 0 :(得分:1)

我认为当您点击菜单项时,它会导致页面PostBack,并且您正在首次加载页面时创建菜单。因此您无法看到菜单单击菜单项。只需在页面加载时调用GetMenuData();方法,而不检查IsPostBack属性。

protected void Page_Load(object sender, EventArgs e)
{
   GetMenuData(); 
}

答案 1 :(得分:1)

为菜单

创建一个表格
CREATE TABLE [dbo].[tblMenuMaster](
[MenuID] [int] IDENTITY(1,1) NOT NULL,
[MenuName] [varchar](100) NULL,
[DisplayOrder] [int] NULL,
PRIMARY KEY CLUSTERED 
(
[MenuID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

为子菜单

创建另一个表
CREATE TABLE [dbo].[tblSubMenuMaster](
[SubMenuID] [int] IDENTITY(1,1) NOT NULL,
[MenuID] [int] NULL,
[SubMenuName] [varchar](100) NULL,
[MainMenuDisplayOrder] [int] NULL,
[DisplayOrder] [int] NULL,
[SubMenuUrl] [varchar](500) NULL,
[VisibleInMenu] [bit] NULL,
PRIMARY KEY CLUSTERED 
(
[SubMenuID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

现在转到母版页面.. HTML代码是:

   <div class="menubar">
        <%--<ul class="tabs">--%>
        <asp:Literal ID="ltMenus" runat="server"></asp:Literal>
        <%--</ul>--%>
    </div>

代码背后的代码是:

private void GenerateMenus()
{
    clsMenu obj = new clsMenu();
    System.Data.DataSet ds = new System.Data.DataSet();
    String PageName = "";
    PageName = Path.GetFileName(Page.AppRelativeVirtualPath);
    ds = obj.GetMenusByRole(GetRoleId(), PageName);

    StringBuilder sb = new StringBuilder("<ul class='tabs'>");

    foreach (System.Data.DataRow row in ds.Tables[0].Rows)
    {
        sb.Append(String.Format("<li class='{0}'><a rel='{1}' href='{1}' > {2} </a> ", Convert.ToString(row["css"]), ResolveUrl(Convert.ToString(row["PagePath"])), Convert.ToString(row["MenuName"])));
        //sb.Append(String.Format("<li '><a rel='{0}' href='{0}' > {1} </a> ", ResolveUrl(Convert.ToString(row["PagePath"])), Convert.ToString(row["MenuName"])));

        System.Data.DataTable t = CCMMUtility.GetFilterDataforIntColumn("MenuID", Convert.ToString(row["MenuID"]), ds.Tables[1]);
        if (t.Rows.Count > 0)
        {
            sb.Append("<ul>");

            for (int i = 0; i < t.Rows.Count; i++)
            {
                sb.Append(String.Format("<li><a href='{0}' class='dir' style='cursor: pointer;'>{1}</a></li>", ResolveUrl(Convert.ToString(t.Rows[i]["PagePath"])), Convert.ToString(t.Rows[i]["PageAliasName"])));
            }

            sb.Append("</ul>");
        }
        sb.Append("</li>");
    }

    sb.Append("</ul>");


    ltMenus.Text = sb.ToString();

}

它需要存储过程来根据角色ID调用菜单的动态,如下所示

CREATE PROCEDURE [dbo].[proc_GetMenusByRole]
(
@RoleId int,  
@PageName varchar(100)
)
AS
SET NOCOUNT ON;
SELECT mm.MenuID, mm.MenuName,dbo.Extract_CssNameForMenuByMenuIDAndPageName(mm.MenuID, @PageName) as css
,dbo.proc_Extract_MenuPageByRoleIDAndMenuID(@RoleId, mm.MenuID)
as PagePath , mm.DisplayOrder   FROM tblMenuMaster mm WHERE mm.MenuID IN (SELECT s.MenuID from tblSiteRolePermissions p INNER JOIN
tblSitePages s ON p.fkSitePageId = s.pkSitePageId
WHERE (p.fkRoleId = @RoleId and p.ViewOnly=1))   
Union All   
select 0 as menuid ,'Change Password' as MenuName,  
case @pagename   
when 'ChangePassword.aspx' then 'active'  
else ''  
end  as css,'~/User/ChangePassword.aspx' as PagePath, 10000 as Displayorder  
ORDER BY DisplayOrder     
SELECT s.MenuID, s.pkSitePageId, s.PageAliasName, s.SitePageName,s.pagepath from tblSiteRolePermissions p 
INNER JOIN tblSitePages s ON p.fkSitePageId = s.pkSitePageId  WHERE (p.fkRoleId =@RoleId and p.ViewOnly=1) ORDER BY s.pkSitePageId  

// new sp从这里开始

CREATE function [dbo].[Extract_CssNameForMenuByMenuIDAndPageName](@MenuID int, 
PageName varchar(100))
returns nvarchar(50)
as begin      
declare @result nvarchar(50) 
set @result = ''    
IF EXISTS (SELECT pkSitePageId FROM tblsitepages WHERE (MenuID = @MenuID) AND (UPPER(SitePageName) = @PageName)) 
 BEGIN    
  SET @result = 'active'    
 END    
return @result    
end  

//使用的另一个sp是

CREATE function [dbo].[proc_Extract_MenuPageByRoleIDAndMenuID]
(@RoleId int, @MenuID int)
returns nvarchar(500) 
as begin          
declare @result nvarchar(500)
SELECT top 1 @result = s.pagepath FROM tblSitePages AS s INNER JOIN tblSiteRolePermissions AS p ON s.pkSitePageId = p.fkSitePageId
WHERE (p.fkRoleId = @RoleId) AND (s.MenuID = @MenuID)  and p.ViewOnly=1
ORDER BY s.pkSitePageId 
return  @result
end  

这只是一种方法,你可以根据你的要求修改它.........

proc_Extract_MenuPageByRoleIDAndMenuID sp用于获取网页名称及其路径,

Extract_CssNameForMenuByMenuIDAndPageName sp用于将活动类设置为第一个 li 表示第一个菜单。 跳这将帮助你..... 它的工作代码..

答案 2 :(得分:0)

您的代码中没有错误它运行良好可能是您的数据中存在错误,您正在添加到menu.May是“ParentMenuid”丢失或可能是错误的