I need to create a custom menu that has a submenu using the ul list from a DataTable
Below is a sample database and a sample HTML ul list with dummy data.
PID MENU Handler PageLangID ParentID IssueID CatID MenuPosition ----------- -------------------- ------------------------ ----------- ----------- ----------- ----------- ------------ 6 Business Category.aspx 1 6 1 16 1 6 Culture Category.aspx 1 6 1 3 1 6 Economy Category.aspx 1 6 1 2 1 6 Finance Category.aspx 1 6 1 19 1 6 Infrastructure Category.aspx 1 6 1 17 1 6 Lifestyle Category.aspx 1 6 1 20 1 6 Others Category.aspx 1 6 1 21 1 6 People Category.aspx 1 6 1 7 1 6 Politics Category.aspx 1 6 1 1 1 6 Sports Category.aspx 1 6 1 4 1 12 1002 Default.aspx 1 12 3 1 1 12 1003 Default.aspx 1 12 4 1 1 12 1006 Default.aspx 1 12 1 1 1 12 1009 Default.aspx 1 12 5 1 1 1 Home Default.aspx 1 0 1 1 10 11 Video Videos.aspx 1 10 1 1 10 2 About Us Page.aspx 1 0 1 1 20 5 Articles Articles.aspx 1 0 1 1 20 6 Categories Category.aspx 1 0
DESIRED HTML OUTPUT
<div id="nav-wrapper"> <ul id="nav" class="dropdown dropdown-linear" > <li><span class="dir"><a href="./">Home</a></span></li> <li ><span class="dir"><a href="ultimate.linear.html">About Us</a></span> <ul > <li><a href="./">History</a></li> <li><a href="./">Our Vision</a></li> <li><a href="./">The Team</a></li> <li><a href="./">Clients</a></li> <li><a href="./">Testimonials</a></li> <li><a href="./">Press</a></li> <li><a href="./">FAQs</a></li> </ul> </li> <li class="active" ><span class="dir"><a href="ultimate.linear-active.html">Categories</a></span> <ul> <li><a href="./">Politics</a></li> <li><a href="./">Economy</a></li> <li><a href="./">Finance</a></li> <li><a href="./">Business</a></li> <li><a href="./">Group News</a></li> <li><a href="./">Culture</a></li> <li><a href="./">Lifestyle</a></li> <li><a href="./">Sports</a></li> <li><a href="./">Infrastructure</a></li> <li><a href="./">Book Review</a></li> <li><a href="./">Others</a></li> </ul> </li> </ul> </div>
I do not want to use nested repeater elements. I would appreciate sample code that I can work with.
UPDATED : this code does not work, definitely I am doing something wrong
protected void Page_Load(object sender, EventArgs e) { DataSet ds = new DataSet(); ds = DataProvider.Connect_Select(strSql); DataTable dt = ds.Tables[0]; //dt.Select("ParentID == 0") ; var s = GenerateUL(dt.Select("ParentID == 0")); Response.Write(s); } private string GenerateUL(var menus) { var sb = new StringBuilder(); sb.AppendLine("<ul>"); foreach (var menu in menus) { if (menu.Menus.Any()) { sb.AppendLine("<li>" + menu.Text); sb.Append(GenerateUL(menu.Menus.AsQueryable())); sb.AppendLine("</li>"); } else sb.AppendLine("<li>" + menu.Text + "</li>"); } sb.AppendLine("</ul>"); return sb.ToString(); }
LATEST UPDATE BASED ON DANI SOLUTION
It seems to work fine with its sample data, but when I use it with my actual data, it throws a StackOverflowException that was unhandled.
Below is a screenshot of the error. 
The error occurs when it goes into the infinate loop type, where PID=6 My actual data, which are shown above, have 23 records and are the result of UNION from different tables, which is the reason that I have several rows in the table, where PID=6 I am afraid that he will also do the same as pid=12 .
Even if I catch the exception, my site still crashes because of this ...
Latest CODE
protected void Page_Load(object sender, EventArgs e) { string strSql = "SELECT DISTINCT PID, MENU, Handler,PageLangID, ParentID,IssueID, CatID,MenuPosition FROM MENUTABLE "; DataSet ds = new DataSet(); ds = DataProvider.Connect_Select(strSql); DataTable table = ds.Tables[0]; DataRow[] parentMenus = table.Select("ParentId = 0"); var sb = new StringBuilder(); string unorderedList = GenerateUL(parentMenus, table, sb); } private string GenerateUL(DataRow[] menu, DataTable table, StringBuilder sb) { sb.AppendLine("<ul>"); try { if (menu.Length > 0) { foreach (DataRow dr in menu) { ctr = ctr + 1; string handler = dr["Handler"].ToString(); string menuText = dr["MENU"].ToString(); string line = String.Format(@"<li><a href=""{0}"">{1}</a>", handler, menuText); sb.Append(line); string pid = dr["PID"].ToString(); DataRow[] subMenu = table.Select(String.Format("ParentId = {0}", pid)); if (subMenu.Length > 0) { var subMenuBuilder = new StringBuilder(); sb.Append(GenerateUL(subMenu, table, subMenuBuilder)); } sb.Append("</li>"); } } } catch (Exception ex) { } sb.Append("</ul>"); return sb.ToString(); }
Update: When I change my query, which gives me the result below, it works fine, but it would be nice to make it work with the actual data that first appears in the question.
PID MENU Handler PageLangID ParentID IssueID CatID MenuPosition ----------- -------------------- ------------------------ ----------- ----------- ----------- ----------- ------------ 1 Home Default.aspx 1 0 1 1 10 2 About Us Page.aspx 1 0 1 1 20 3 News News.aspx 1 0 1 1 30 5 Articles Articles.aspx 1 0 1 1 20 6 Categories Category.aspx 1 0 1 1 25