菜单的内容来自数据库,根据权限选定,如何动态绑定到menu控件?

解决方案 »

  1.   

    http://www.microsoft.com/china/msdn/events/webcasts/shared/webcast/episode.aspx?newsID=1242379
      

  2.   

    这个东西是用在masterpage而数据来源是sitmap的,如果不是专业使用,手动在添加item好了http://do-net.xicp.net
    .NET技术群
    QQ群4329478,7019839,10058555
    ---------------------------------------------------------
    个人QQ303864496
    msn:[email protected]
    成都理工大三,寻成都地区兼职,熟悉asp.net/C#/webservice
    NeT(Nebula Team)结交愿意郑州发展的.net技术朋友(19-25岁)...
    email:[email protected]
      

  3.   

    本来我用aspnetmenu控件的,可以根据权限动态绑定。现在在学习 asp。net 2.0,想用自带的menu控件达到同样目的。唉,就是不行
      

  4.   

    可以把数据源转换为XML文档,然后帮定到MENU控件。
      

  5.   

    不能动态绑定,只能帮定静态xml文件.自写方法生成把有事直接联系,我一般不会二次浏览一个帖子。
    http://do-net.xicp.net
    .NET技术群
    QQ群4329404可加,4329478满,7019839满,10058555管理员不在
    MSN群138459
    ---------------------------------------------------------
    个人QQ303864496
    msn:[email protected]
    成都理工大三,寻成都地区兼职,熟悉asp.net/C#/webservice
    NeT(Nebula Team)结交愿意郑州发展的.net技术朋友(19-25岁)...
    email:[email protected]
      

  6.   

    I have the way. It is not very difficult. I use MS SQL Server + ASP.NET.
    1) use SQLServer user defined function to select a subset menu data for a user. the data is organized as "Hierarchily". The source codes are very long, but basically you can get idea from a demo script from SQLServer Books Online.
    2) use a stack in the C#, like:        TQuery qryMenu;
            qryMenu = new TQuery();
            qryMenu.CommandText = "Select AtLevel, MenuTitle, URL from fnMISMnu(?) ";
            OleDbParameter para = qryMenu.Parameters.Add("currUser", 
                     OleDbType.VarChar, 50);
            para.Value = USER_NAME;
            qryMenu.Open();
            MenuItem[] parentItems = new MenuItem[6];
            MenuItem currItem;        int nCurrLevel, nLastLevel;
            nLastLevel = -1;
            while (!qryMenu.Eof)
            {
                currItem = new MenuItem();
                currItem.Text = qryMenu.Value("MenuTitle").ToString();
                nCurrLevel = int.Parse(qryMenu.Value("atLevel").ToString()) - 1;
                if (nCurrLevel == 0)
                {
                    parentItems[nCurrLevel] = currItem;
                    mnuMain.Items.Add(currItem);
                    qryMenu.MoveNext();
                    continue;
                }
                if (nCurrLevel > nLastLevel)
                    parentItems[nCurrLevel] = currItem;
                parentItems[nCurrLevel - 1].ChildItems.Add(currItem);
                nLastLevel = nCurrLevel;
                qryMenu.MoveNext();
            };
      

  7.   

    Here is the User Defined function for SQL Server(Oracle has a easier way, using "connect by"):
    -----------------------------table stored menu file:------------------
    ...
    --------------------------------------------------------------------------------
    create  Function [dbo].[fnMISMnu]( @Schema varchar(50) = '' )
    Returns @Menu TABLE ( MenuID varchar(50), ParentMenuID varchar(50),  ParentTab varchar(80), MenuTitle varchar(80), DisplayTitle varchar(100), AtLevel int, IconFile varchar(80), IsAnonymousPage int, DispOrder int, TabDefaultPage varchar(50) )  /*
     *Author: chengj
     *Function: select hierarchy menu items according to user's role
     *  
     *Version History
     *Dec 14: Set a default page for a tab to the 1st child.
     */BEGIN
    Declare @MenuID varchar(50), @ParentMenuID varchar(50), @MenuTitle varchar(80), @Current varchar(50), @ParentTab varchar(80),
    @DisplayTitle varchar(100), @Level int, @IconFile varchar(80), @IsAnonymousPage int, @DispOrder int

    Declare @Stack TABLE ( MenuID varchar(50), ParentMenuID varchar(50), MenuTitle varchar(80), ParentTab varchar(80),
    DisplayTitle varchar(100), atLevel int, IconFile varchar(80), IsAnonymousPage int , DispOrder int) INSERT INTO @Stack( MenuID, ParentMenuID, atLevel, MenuTitle, DisplayTitle, IconFile, IsAnonymousPage, DispOrder, ParentTab) 
    Select MenuID, NULL, 1, MenuTitle, DisplayTitle, IconFile, IsAnonymousPage, DispOrder, ParentTab
    From dbo.MisPage 
    Where IsNavMenu = 1
    AND ( ParentMenuID is NULL or ParentMenuID = '')
    Order By DispOrder  desc
    SELECT @Level = 1
    WHILE (@Level > 0)
    BEGIN
        IF NOT EXISTS (SELECT MenuID FROM @Stack WHERE atLevel = @Level)
           SELECT @Level = @Level - 1
    ELSE BEGIN
    SELECT  @Current = menuID, @parentMenuID = parentMenuID, @IconFile = IconFile, @DispOrder= DispOrder,
    @DisplayTitle= DisplayTitle, @MenuTitle = MenuTitle, @IsAnonymousPage = IsAnonymousPage, @ParentTab = ParentTab
                   FROM @Stack WHERE atLevel = @Level

    INSERT INTO @Menu(MenuID, parentMenuID, atLevel, MenuTitle, DisplayTitle, IconFile,IsAnonymousPage, DispOrder, ParentTab)
    VALUES(@current, @parentMenuID, @level, @MenuTitle, @DisplayTitle, @IconFile, @IsAnonymousPage, @DispOrder, @ParentTab )          DELETE FROM @Stack
             WHERE atLevel = @Level
             AND MenuID = @current INSERT INTO @Stack( MenuID, ParentMenuID, atLevel, MenuTitle, DisplayTitle, IconFile, IsAnonymousPage, DispOrder, ParentTab) 
                 SELECT MenuID, ParentMenuID, @Level + 1, H.MenuTitle, H.DisplayTitle, H.IconFile, IsAnonymousPage, DispOrder, ParentTab
                 FROM MisPage H
                 WHERE H.ParentMenuID = @current
    Order By DispOrder desc          IF @@ROWCOUNT > 0  SELECT @Level = @Level + 1
      END
    END Delete From @Menu Where IsAnonymousPage = 0 And ( MenuID not in (
    select PageID From MisUserPermission Where UserID = @Schema ) ) --Setup the default page to the first child:
    declare @No1stChild varchar(50)
    declare curAA cursor for 
    select menuID from @Menu 
    For update open curAA
    while (1=1) Begin
    fetch next from curAA into @current
    if @@fetch_status <> 0 break
    Set @No1stChild = null Select @No1stChild = MenuID
    From @Menu Where ParentMenuID = @Current
    order by DispOrder desc if @No1stChild is null continue update @Menu Set TabDefaultPage = @No1stChild
    Where current of curAA
    End
    close curAA
    deallocate curAA

    -- set menu level index as 0 based. 
    update @menu set AtLevel = AtLevel 
    RETURN END
    -------------------------------------------------------------------------
      

  8.   

    Thank you very much.Let me try
      

  9.   

    能详细指点一下吗?通过sql server2000 获得数据,动态绑定menu。最好给出关键代码
      

  10.   

    可以这样
    根据不同的权限组,生成不同的XML文件。当用户登陆时,根据权限组让menu控件绑定该XML文件即可!
    如果XML都手动写死是很简单的。麻烦的是这些权限的XML需要维护,即权限会变更。这样就要写遍历XML文件的方法了。
    最近自己的项目中有这方面的内容,是我负责的。
    我的方法是:
    用.NET2005的treeview控件绑定基本XML文件,让节点都显示CheckBox,通过遍历treeview中的CheckBox是否被check住生成相应的xml文件。
    这里又涉及到了,如何写xml文件的问题。xml文件的格式是像下面这样的:
    <菜单>
      <订单处理>
        <menu title="数学书" url="Default2.aspx"/>
        <menu title="几何书" url="Default2.aspx"/>
        <客户信息>
          <menu title ="日本" url="Default2.aspx"/>
          <menu title ="大连" url="Default2.aspx"/>
        <客户信息>
    <菜单>
    这里的menu节点与menu控件中的datamember绑定,title与其他的field绑定。下面是我的生成XML的方法:
      

  11.   

    #region 创建权限菜单XML
        /// <summary>
        /// 创建权限菜单XML
        /// </summary>
        /// <param name="tnc"></param>
        /// <param name="textWriter"></param>
        protected void creatRoleMenu(TreeNodeCollection tnc, XmlTextWriter textWriter)
        {
            //pre node info.
            string preNoderoot = "";
            TreeNode preNode = null;
            foreach(TreeNode curnode in tnc)
            {
                //current node info.
                string curNoderoot = curnode.Parent.Text;
                TreeNode node = curnode;
                while (curNoderoot != "books")
                {
                    node = node.Parent;
                    curNoderoot = node.Parent.Text;
                }
                curNoderoot = node.Text;
                //all
                if (preNoderoot == "" || curNoderoot == preNoderoot)
                {
                    if (preNode == null)
                    {
                        string[] curnodepath = curnode.ValuePath.Split('/');
                        for (int i = 1; i < curnode.Depth; i++)
                        {
                            textWriter.WriteStartElement(curnodepath[i]);
                        }                    textWriter.WriteStartElement("book");
                        textWriter.WriteAttributeString("title", curnode.Text);
                        textWriter.WriteAttributeString("url", curnode.NavigateUrl);
                        textWriter.WriteEndElement();
                        preNode = curnode;
                        preNoderoot = curNoderoot;
                    }
                    else
                    {
                        //与前一节点通层的节点
                        if (curnode.Parent == preNode.Parent)
                        {
                            textWriter.WriteStartElement("book");
                            textWriter.WriteAttributeString("title", curnode.Text);
                            textWriter.WriteAttributeString("url", curnode.NavigateUrl);
                            textWriter.WriteEndElement();
                            preNode = curnode;
                            preNoderoot = curNoderoot;
                        }
                            //与前一节点有相同的祖先,且有相同的父亲节点
                        else if (curnode.Parent != preNode.Parent && curNoderoot == preNoderoot && curnode.Depth == preNode.Depth)
                        {
                            textWriter.WriteEndElement();                        textWriter.WriteStartElement(curnode.Parent.Text);                        textWriter.WriteStartElement("book");
                            textWriter.WriteAttributeString("title", curnode.Text);
                            textWriter.WriteAttributeString("url", curnode.NavigateUrl);
                            textWriter.WriteEndElement();                        preNode = curnode;
                            preNoderoot = curNoderoot;
                        }
                            //有相同的祖先,但是比前一节点层数怎加一层
                        else if (curnode.Parent != preNode.Parent && curNoderoot == preNoderoot && curnode.Depth > preNode.Depth)
                        {
                            string[] curpathList = curnode.ValuePath.Split('/');
                            //string[] prepathList = preNode.ValuePath.Split('/');
                            //特殊情况
                            if (curnode.Parent.Depth == preNode.Depth && curnode.Parent.Parent.Text == preNode.Parent.Text)
                            {
                                //textWriter.WriteEndElement();
                                for (int i = preNode.Depth; i < curnode.Depth; i++)
                                {
                                    textWriter.WriteStartElement(curpathList[i]);
                                }
                            }
                            else if (curnode.Parent.Depth == preNode.Depth && curnode.Parent.Parent.Text != preNode.Parent.Text)
                            {
                                textWriter.WriteEndElement();
                                for (int i = preNode.Depth - 1; i < curnode.Depth; i++)
                                {
                                    textWriter.WriteStartElement(curpathList[i]);
                                }
                            }
                            else //if (curnode.Depth > preNode.Depth + 1)
                            {
                                for (int i = preNode.Depth; i < curnode.Depth; i++)
                                {
                                    textWriter.WriteStartElement(curpathList[i]);
                                }
                            }                        textWriter.WriteStartElement("book");
                            textWriter.WriteAttributeString("title", curnode.Text);
                            textWriter.WriteAttributeString("url", curnode.NavigateUrl);
                            textWriter.WriteEndElement();                        preNode = curnode;
                            preNoderoot = curNoderoot;
                        }
                            //与前一节点有相同的祖先,但是没有相同的父亲,且比前一节点少一层
                        else if (curnode.Parent != preNode.Parent && curNoderoot == preNoderoot && curnode.Depth < preNode.Depth)
                        {
                            //前一个节点尾部处理
                            for (int i = 0; i < (preNode.Depth - curnode.Depth) + 1; i++)
                            {
                                textWriter.WriteEndElement();
                            }
                            ////当前节点的开始处理
                            //string[] pathList = curnode.ValuePath.Split('/');
                            ////特殊情况
                            //for (int i = curnode.Depth - preNode.Depth; i < curnode.Depth; i++)
                            //{
                            //    textWriter.WriteStartElement(pathList[i]);
                            //}
                            textWriter.WriteStartElement(curnode.Parent.Text);
                            textWriter.WriteStartElement("book");
                            textWriter.WriteAttributeString("title", curnode.Text);
                            textWriter.WriteAttributeString("url", curnode.NavigateUrl);
                            textWriter.WriteEndElement();                        preNode = curnode;
                            preNoderoot = curNoderoot;
                        }
                        //XML元素的结尾部分处理
                        if (curNoderoot == preNoderoot && curnode.Parent != preNode.Parent)
                        {
                            textWriter.WriteEndElement();
                        }
                    }
                }
                    //与前一节点没有相同的祖先,即遍历到菜单的另一格根节点
                else if (curNoderoot != preNoderoot)
                {
                    //处理新的菜单根节点开始
                    for (int i = 1; i < preNode.Depth; i++ )
                    {
                        textWriter.WriteEndElement();
                    }                                //textWriter.WriteStartElement(curnode.Parent.Text);
                    string[] curnodepath = curnode.ValuePath.Split('/');
                    for (int i = 1; i < curnode.Depth; i++)
                    {
                        textWriter.WriteStartElement(curnodepath[i]);
                    }                textWriter.WriteStartElement("book");
                    textWriter.WriteAttributeString("title", curnode.Text);
                    textWriter.WriteAttributeString("url", curnode.NavigateUrl);
                    textWriter.WriteEndElement();
                    preNode = curnode;
                    preNoderoot = curNoderoot;
                }
            }
        }
        #endregion希望交流一下
    谢谢