Lea*_*ing 5 c# asp.net html-lists
我需要生成一个自定义菜单,其子菜单使用列表ul DataTable
下面是数据库示例和带有虚拟数据的示例HTML ul列表.
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
Run Code Online (Sandbox Code Playgroud)
期望的HTML输出
<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>
Run Code Online (Sandbox Code Playgroud)
我不想使用嵌套的转发器控件.我很感激我可以使用的示例代码.
更新:此代码不起作用,我肯定做错了什么
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();
}
Run Code Online (Sandbox Code Playgroud)
基于DANI解决方案的最新更新
它似乎与他的数据样本工作正常,但当我使用它与我的实际数据时,它生成StackOverflowException未处理.
下面是错误的屏幕截图.

当它进入infinate循环时产生错误,其中PID=6我上面显示的实际数据有23条记录并且是来自不同tabel的UNION的结果,这是我在表中有多行的原因,PID=6我担心它也会做同样的地方pid=12.
即使我抓住了异常我的网站仍然因此而崩溃......
最新代码
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();
}
Run Code Online (Sandbox Code Playgroud)
更新:当我更改我的查询得到下面的结果然后它工作正常,但最好使它工作在问题中首先显示的实际数据.
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
Run Code Online (Sandbox Code Playgroud)
Den*_*els 10
我在我这边创建了一个稍微简单的表结构,因为我们只需要以下列来示例:
样本数据:
正如您在此示例中所看到的,我们对Product有一个3向深层次结构,其余项目没有子项.

代码背后:
以下代码执行以下操作:
检查项是否是任何节点的父项并递归获取其子项.
protected void Page_Load(object sender, EventArgs e)
{
DataSet ds = new DataSet();
ds = DataProvider.Connect_Select("SELECT * FROM Menu");
DataTable table = ds.Tables[0];
DataRow[] parentMenus = table.Select("ParentId = 0");
var sb = new StringBuilder();
string unorderedList = GenerateUL(parentMenus, table,sb);
Response.Write(unorderedList);
}
private string GenerateUL(DataRow[] menu,DataTable table,StringBuilder sb)
{
sb.AppendLine("<ul>");
if (menu.Length > 0)
{
foreach (DataRow dr in menu)
{
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>");
}
}
sb.Append("</ul>");
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)最终结果:

编辑:
问题是代码基于ParentID构造菜单,对于ID = 6,ParentID也恰好是6.所以6个调用6并且我们有一个无限循环,很棒.
现在我们知道问题是什么,我们可以通过简单的检查来递归地构造子菜单,只有ParentId != PID这里是更新的代码:
private string GenerateUL(DataRow[] menu, DataTable table, StringBuilder sb)
{
sb.AppendLine("<ul>");
if (menu.Length > 0)
{
foreach (DataRow dr in menu)
{
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();
string parentId = dr["ParentId"].ToString();
DataRow[] subMenu = table.Select(String.Format("ParentId = {0}", pid));
if (subMenu.Length > 0 && !pid.Equals(parentId))
{
var subMenuBuilder = new StringBuilder();
sb.Append(GenerateUL(subMenu, table, subMenuBuilder));
}
sb.Append("</li>");
}
}
sb.Append("</ul>");
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
我认为重要的是通过在调试器中单步执行它来实际理解这段代码是如何工作的,这样你就可以在出现任何其他问题时进行更改.
| 归档时间: |
|
| 查看次数: |
23225 次 |
| 最近记录: |