2011-01-26 107 views
10

我想從列表中獲取一些值,然後使用此數據創建一個html表格,但無法使其正常工作。從列表中創建HTML表格

我:

HtmlTable table = new HtmlTable(); 
HtmlTableRow row; 
HtmlTableCell cell; 

foreach(var item in Name) 
{ 
    row = new HtmlTableRow(); 

    foreach(var familyName in item.familyName) 
    { 
     cell = new HtmlTableCell(); 
     cell.InnerText = item.familyName.ToString(); 
     row.Cells.Add(cell); 
    } 
    foreach (var givenName in item.givenName) 
    { 
     cell = new HtmlTableCell(); 
     cell.InnerText = item.givenName.ToString(); 
     row.Cells.Add(cell); 
    } 

    table.Rows.Add(row); 
} 
this.Controls.Add(table); 

當我通過調試步驟,我可以看到row.Cells.Add(小區)包含在第一循環中的姓氏和名字在第二循環中,但隨後事情似乎是錯誤的,我無法使用此數據在頁面上顯示錶格。

當我檢查table.rows.add(行),它說,「base {System.SystemException} = {"'HtmlTableRow' does not support the InnerText property."}

我在做什麼錯在這裏?

+0

一個不相關的問題,但什麼是你想在內部foreach循環呢?你不使用迭代器變量(familyName,givenName)。 – 2011-01-26 10:01:15

+0

嗨,這是一個錯誤,現在改變它,謝謝。 – peter 2011-01-26 13:16:26

回答

10

我已經通過你的代碼,我不能複製你提到的錯誤。

這很難說肯定沒有看到你的數據結構Name但一些觀察:

I.如果familyName是一個字符串,你的內心foreach將爲串中的每個字符執行一次。這可能不是是你想要的,因爲它會輸出姓氏×次數,其中x = surname.length。

這將導致每行的表格單元格數量不相等,除非您的所有姓氏長度相同。

所以,我要說擺脫

foreach(var familyName in item.familyName){...} 

循環和剛剛離開的代碼裏面所以它會輸出姓只有一次。

二,我是猜測item.givenName是一個數組或集合,例如列表<>字符串?如果是這樣,你可以只使用

cell.InnerText = givenName; 

注意,這將仍然給你每行的表格單元格的數量不均,因爲人們已經說過forenames ;-)

的不同數字,你真的應該使用內置的控制器來完成這種事情 - Repeater可能是最好的選擇。

E.g.

標記

<asp:Repeater runat="server" id="rptNames" onItemDataBound="rptName_ItemDataBound" > 
     <HeaderTemplate> 
      <table> 
       <tr> 
        <td>Given Name(s)</td> 
        <td>Family Name</td> 
       </tr> 
     </HeaderTemplate> 
     <ItemTemplate> 
      <tr> 
       <td><%# Eval("FamilyName") %></td> 
       <td> 
        <asp:Label runat="server" id="lGivenNames" /> 
       </td> 
      </tr>    
     <ItemTemplate> 
     <FooterTemplate> 
      </table> 
     </FooterTemplate> 
</asp:Repeater> 

代碼隱藏

通過Page_Load可能觸發 - 只要你轉發器綁定到你的Name集合:

rptNames.DataSource = Name; 

rptNames.DataBind(); 

要輸出GivenName是你使用項目DataBound事件被調用中繼器的每一行:

protected void rptNames_ItemDataBound(object sender, RepeaterItemEventArgs e){ 
    //Not interested the Header and Footer rows 
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem){ 
     Label l = ((Label)e.Item.FindControl("lGivenNames")); 

     string[] arrGivenNames = ((FullName)e.Item.DataItem).GivenNames; 

     foreach (string n in arrGivenNames){//could use a StringBuilder for a performance boost. 
      l.Text += n + "&nbsp;";   //Use a regular space if using it for Winforms 
     } 
     //For even slicker code, replace the Label in your repeater with another repeater and bind to that. Google `nested repeater` for a how to. 
    } 
} 

HTH。

全碼

<h2>Doing it by hand - manually building up an HTML Table</h2> 

<asp:Panel runat="server" ID="pnl1"> 
</asp:Panel> 

<h2>With a Repeater</h2> 

<asp:Repeater runat="server" id="rptNames" onItemDataBound="rptName_ItemDataBound" > 
     <HeaderTemplate> 
      <table border="1" style="border-color:Red;"> 
       <tr> 
        <td>Given Name(s)</td> 
        <td>Family Name</td> 
       </tr> 
     </HeaderTemplate> 
     <ItemTemplate> 
      <tr> 
       <td><%# Eval("FamilyName") %></td> 
       <td> 
        <asp:Label runat="server" id="lGivenNames" /> 
       </td> 
      </tr>  
     </ItemTemplate>  
     <FooterTemplate> 
      </table> 
     </FooterTemplate> 
</asp:Repeater> 


    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Web; 
    using System.Web.UI; 
    using System.Web.UI.WebControls; 
    using System.Web.UI.HtmlControls; 

    namespace Testbed.WebControls 
    { 
     internal class FullName{ 
      public string FamilyName{get;set;} 
      public string[] GivenNames{get;set;} 
      public FullName(){ 

      } 
      public FullName(string[] _givenNames, string _familyName) 
      { 
       FamilyName = _familyName; 
       GivenNames = _givenNames; 
      } 
     } 
     public partial class HTMLTables : System.Web.UI.Page 
     { 
      List<FullName> Name; 

      protected void Page_Load(object sender, EventArgs e) 
      { 
       this.Name = new List<FullName>(); 
       Name.Add(new FullName(new string[]{"Kylie"},"Minogue")); 
       Name.Add(new FullName(new string[]{"Angelina", "Kate", "Very-Lovely"}, "Jolie")); 
       Name.Add(new FullName(new string[]{"Audrey", "Veronica"},"Hepburn")); 

       HtmlTable table = new HtmlTable(); 
       table.Border = 1; 
       HtmlTableRow row; 
       HtmlTableCell cell; 

       row = new HtmlTableRow(); 
       cell = new HtmlTableCell(); 
       cell.InnerText = "Given Name"; 
       row.Cells.Add(cell); 

       cell = new HtmlTableCell(); 
       cell.InnerText = "Family Name"; 
       row.Cells.Add(cell); 


       foreach (var item in Name) 
       { 
        row = new HtmlTableRow(); 

        //foreach (var familyName in item.FamilyName){ 
         cell = new HtmlTableCell(); 
         cell.InnerText = item.FamilyName.ToString(); 
         row.Cells.Add(cell); 
        //} 
        foreach (string givenName in item.GivenNames) 
        { 
         cell = new HtmlTableCell(); 
         cell.InnerText = givenName.ToString(); 
         row.Cells.Add(cell); 
        } 

        table.Rows.Add(row); 
       } 
       this.pnl1.Controls.Add(table); 


       //Or do it with a repeater 
       rptNames.DataSource = Name; 
       rptNames.DataBind(); 

      } 

      //This gets called everytime a data object gets bound to a repeater row 
      protected void rptName_ItemDataBound(object sender, RepeaterItemEventArgs e){ 
       switch(e.Item.ItemType){ 
        case ListItemType.Item: 
        case ListItemType.AlternatingItem: 
         string[] arrGivenNames = ((FullName)e.Item.DataItem).GivenNames; 

         foreach(string n in arrGivenNames){ 
          ((Label)e.Item.FindControl("lGivenNames")).Text += n + @"&nbsp;"; 
         } 
        break; 

        default: 

        break; 
       } 
      } 
     } 
    }