簡體   English   中英

使用c#作為ul列表而不是Asp.net菜單控件從數據表生成嵌套菜單

[英]Generate Nested Menu from datatable using c# as ul list not Asp.net Menu control

我需要生成一個自定義菜單,其子菜單使用DataTable列表ul

下面是數據庫示例和帶有虛擬數據的示例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           

期望的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> 

我不想使用嵌套的轉發器控件。 我很感激我可以使用的示例代碼。

更新 :此代碼不起作用,我肯定做錯了什么

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();
}

基於DANI解決方案的最新更新

它似乎與他的數據樣本工作正常,但當我使用它與我的實際數據時,它生成StackOverflowException未處理。

下面是錯誤的屏幕截圖。 在此輸入圖像描述

當它進入無限循環時產生錯誤,其中PID=6我上面顯示的實際數據有23條記錄並且是來自不同表格的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();
}

更新:當我更改我的查詢得到下面的結果然后它工作正常,但最好使它工作在問題中首先顯示的實際數據。

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

我在我這邊創建了一個稍微簡單的表結構,因為我們只需要以下列來示例:

  1. PID
  2. 菜單
  3. 處理器
  4. PARENTID

樣本數據:

正如您在此示例中所看到的,我們對Product有一個3向深層次結構,其余項目沒有子項。

在此輸入圖像描述

代碼背后:

以下代碼執行以下操作:

  1. 首先獲取沒有父母的所有項目並開始循環
  2. 檢查項是否是任何節點的父項並遞歸獲取其子項。

     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(); } 

最終結果:

在此輸入圖像描述

編輯:

問題是代碼基於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();
}

我認為重要的是通過在調試器中單步執行它來實際理解這段代碼是如何工作的,這樣你就可以在出現任何其他問題時進行更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM