简体   繁体   中英

ASP Control unordered list UL with nested list

I tried Menu, TreeView, BulletedList, Repeater, HtmlGenericControl but without result.

What I would like to have is asp control which render something:

<ul>
    <li><a href="#">Item 1</a></li>
    <li><a href="#">Item 2</a>
        <ul>
            <li><a href="#">Item 2.1</a></li>
        </ul>
    </li>
</ul>

For example menu it's render SPAN no UL.

<asp:Menu runat="server">
     <Items>
          <asp:MenuItem Text="Item 1" />
          <asp:MenuItem Text="Item 2">
             <asp:MenuItem Text="Item 2.1" />
          </asp:MenuItem>
    </Items>
</asp:Menu>

I also tried

<asp:Menu RenderingMode="MenuRenderingMode" />

But it's not working. I'm using ASP.NET 3.5.

I need create dynamic ul list and after click on item it will check in db if exist nested items and add them to clicked list as nested ul.

I cant render whole menu at once because of performence.

Sorry if I'm not very clear. Thanks for help.

You need to use nested repeaters:

<asp:Repeater ID="rptFoo" runat="server" OnItemDataBound="rptFoo_ItemDataBound">
   <HeaderTemplate>
     <ul>
   </HeaderTemplate>
   <ItemTemplate>
       <li>
           <asp:HyperLink ID="lnkFoo" runat="server" />
           <asp:Repeater ID="rptBar" runat="server" OnItemDataBound="rptBar_ItemDataBound">
               <HeaderTemplate>
                  <ul>
               </HeaderTemplate>
               <ItemTemplate>
                    <li><asp:HyperLink ID="lnkBar" runat="server" /></li>
               </ItemTemplate> 
               <FooterTemplate>
                  </ul>
               </FooterTemplate>
           </asp:Repeater>
      </li>
   </ItemTemplate> 
   <FooterTemplate>
     </ul>
   </FooterTemplate>
</asp:Repeater>

And then in the ItemDataBound handler, you need to check whether each top level item has child elements, if it does, assign those elements to the sub repeater and databind, else hide it.

protected void rptFoo_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
    {
        FooType obj = (FooType)e.Item.DataItem;
        Repeater rptBar = (Repeater)e.Item.FindControl("rptBar");
        if(obj.Children.Count() > 0)
        {
            rptBar.DataSource = obj.Children;
            rptBar.DataBind();
        }
        else
        {
            rptBar.Visible = false;
        }
    }
}

If you just need access to the ul and li elements from codebehind you can easily add a runat="server" attribute to them. The id attribute is necessary in order to be able to reference a single element:

<ul id="mainMenu" runat="server">
    <li id="mainMenuItem1" runat="server"><a href="#">Item 1</a></li>
    <li id="mainMenuItem2" runat="server"><a href="#">Item 2</a>
        <ul id="subMenu" runat="server">
            <li id="subMenuItem1" runat="server"><a href="#">Item 2.1</a></li>
        </ul>
    </li>
</ul>

This structure could also be build from codebehind using HtmlGenericControl s.

Another option could be to use user controls: http://msdn.microsoft.com/en-us/library/y6wb1a0e%28v=vs.100%29.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM