Search code examples
c#asp.net-mvchtml-generationhtmlgenericcontrol

Controls.Add removing previous items from list


I am attempting to create a dynamic menu in my controller that i am then rendering to my view. What i am finding is that Controls.Add is removing items from my list and i end up only displaying the final item. How do i make sure that it displays all of the item in my list and how do I finish displaying the child elements since i am creating a dynamic menu?

public string CreateDynamicMenu()   
        {
            HtmlGenericControl navbar = new HtmlGenericControl("nav");
            navbar.Attributes.Add("class", "navbar navbar-default");
            HtmlGenericControl containerDiv = new HtmlGenericControl("div");
            containerDiv.Attributes.Add("class", "container-fluid");
            HtmlGenericControl collapseDiv = new HtmlGenericControl("div");
            collapseDiv.Attributes.Add("class", "collapse navbar-collapse");
            HtmlGenericControl navUl = new HtmlGenericControl("ul");
            navUl.Attributes.Add("class", "nav navbar-nav");
            HtmlGenericControl dropdownLi = new HtmlGenericControl("li");
            dropdownLi.Attributes.Add("class", "dropdown");
            HtmlGenericControl mainMenuA = new HtmlGenericControl("a");


            var myMenu = menuListForUserG.GetMenus(Global.CurrentProfile.UserID).OrderBy(x => x.MenuOrder).ThenBy(y => y.MenuName);
            var navbarmenu = myMenu.Where(x => x.ParentID == null);

            foreach (var item in navbarmenu)
            {    
                mainMenuA.InnerText = item.MenuName;
                dropdownLi.Controls.Add(mainMenuA);
                navUl.Controls.Add(dropdownLi);                    
            }  

            collapseDiv.Controls.Add(navUl);
            containerDiv.Controls.Add(collapseDiv);
            navbar.Controls.Add(containerDiv);    

            StringBuilder htmlStringBuilder = new StringBuilder();
            HtmlTextWriter htmlStringWriter = new HtmlTextWriter(new StringWriter(htmlStringBuilder));
            navbar.RenderControl(htmlStringWriter);
            String output = htmlStringBuilder.ToString();
            return output; }

Solution

  • The problem is that you are adding the same instance of dropdownLi and mainMenuA in the loop over and over. I suppose that Control.Add will not add duplicates into the list, so the control is effectively added only once. With the final run of the loop, you change the text to the text of the last item.

    In order to fix this, you need to create new instances as follows:

    foreach (var item in navbarmenu)
    {
        // Move the following lines from outside the loop inside
        HtmlGenericControl dropdownLi = new HtmlGenericControl("li");
        dropdownLi.Attributes.Add("class", "dropdown");
        HtmlGenericControl mainMenuA = new HtmlGenericControl("a");    
        mainMenuA.InnerText = item.MenuName;
        dropdownLi.Controls.Add(mainMenuA);
        navUl.Controls.Add(dropdownLi);                    
    }