从列表中创建HTML表格

11

我想从列表中获取一些值,然后用这些数据创建一个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(cell)包含了姓氏,第二个循环中则包含名字,但是在某个地方出现了问题,导致无法使用这些数据在网页上显示表格。

当我检查table.rows.add(row)时,它提示:

base {System.SystemException} = {"'HtmlTableRow' does not support the InnerText property."}

我做错了什么?


一个不相关的问题,但是你在内部foreach循环中想要做什么?你没有在那里使用迭代变量(familyName, givenName)。 - Elian Ebbing
嗨,那是一个错误,现在已经更正了,谢谢。 - peter
3
你可能应该使用一个中继器来完成这个任务... - Mike Cole
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
10

我已经审查了你的代码,但无法重现你提到的错误。

没有看到你的数据结构 Name ,很难肯定地说,但有几个观察点:

一、如果 familyName 是一个字符串,你的内部 foreach 将为字符串中的每个字符执行一次。这 可能不是 你想要的结果,因为它会输出一个姓氏 x 次,其中 x = 姓氏长度。

这将导致每行单元格数量不等,除非所有的姓氏长度都相同。

所以我建议把它去掉。

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

循环并仅保留其中的代码,这样它只会输出姓氏一次。

II. 我猜 item.givenName 是一个字符串的数组或集合,比如 List<> ? 如果是这样的话,您可以使用

cell.InnerText = givenName;  

请注意,这仍会导致每行表格单元格的数量不均,因为人们有不同数量的名字;-)

话虽如此,你真的应该使用内置控件来完成这种事情 - Repeater可能是最好的选择。

例如:

标记

<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>

CodeBehind

很可能由Page_Load触发-只需将您的重复器绑定到您的Name集合:

rptNames.DataSource = Name;

rptNames.DataBind();

要输出GivenName,您可以使用ItemDataBound事件,该事件会在重复项的每一行中调用:

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

1
没问题。希望它能解决问题。+1 分的礼貌 :-) - immutabl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,