HtmlTable 在迭代时丢失其 HtmlRows 并将它们添加到标记中的 HtmlTable

HtmlTable loses its HtmlRows while iterating and adding them to a HtmlTable in markup

我在我的代码隐藏中创建了两个 HtmlTable(s),每个都有各自的 HtmlTableRow(s)。创建这些后,我需要按特定顺序将它们添加到标记中的 <table name="teamoptionstable"> 元素。但是当我循环将每个 HtmlTableRow 添加到我的 teamoptionstable 时,HtmlTable 似乎在我迭代时删除了行。这是代码:

HtmlTable gaTable = new HtmlTable();
HtmlTable supportTable = new HtmlTable();

HtmlTableRow gaHeaderRow = new HtmlTableRow();
gaHeaderRow.Cells.Add(new HtmlTableCell {
    InnerHtml = "<tr id='gaHeaderLeft'><th colspan='3'>G&A</th></tr>"
});
gaTable.Rows.Add(gaHeaderRow);

HtmlTableRow supportHeaderRow = new HtmlTableRow();
supportHeaderRow.Cells.Add(new HtmlTableCell {
    InnerHtml = "<tr id='supportHeaderLeft'><th colspan='3'>Support</th></tr>"
});
supportTable.Rows.Add(supportHeaderRow);

using(DataTable departmentList = Database.ObjectList_Get(Database.ObjectType.Department)) {
    foreach(DataRow department in departmentList.Rows) {
        int departmentId = Convert.ToInt32(department["department_id"]);
        string departmentName = department["name"].ToString();
        HtmlTableRow data = new HtmlTableRow();
        if (...) {
            data.Cells.Add(...);
            data.Cells.Add(...);
            data.Cells.Add(...);
            gaTable.Rows.Add(data);
        } else if (...) {
            data.Cells.Add(...);
            data.Cells.Add(...);
            data.Cells.Add(...);
            supportTable.Rows.Add(data);
        }
    }
}

for (int i = 0; i < gaTable.Rows.Count; i++) {
    teamoptionstable.Rows.Add(gaTable.Rows[i]);
}
for (int i = 0; i < supportTable.Rows.Count; i++) {
    teamoptionstable.Rows.Add(supportTable.Rows[i]);
}

问题出在我的for循环的最后。当它第一次迭代时,由于某种原因,gaTable.Rows.Count 发生变化,它减少了一个。所以我最终向 teamoptionstable 添加了更少的行。这是团队选项表的标记:

<table class="table table-condensed table-striped" id="teamoptionstable" name="teamoptionstable" runat="server">
    <thead>
        <tr>
            <th>Team</th>
            <th>Primary Rule</th>
            <th>Secondary Rule</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>

这是因为HtmlTableRow是引用类型。因此,当您将对该行的引用添加到另一个 table 时,您就是从第一个 table 中删除引用。这类似于其他语言中的指针。

因此,当您从 0 开始循环时,您只会遍历一半的行。

例子。这是您的行集合:

Table 1: [0][1][2][3][4][5]

您使用索引 0 并将其添加到新的 table。你现在只剩下这个了,因为你从你的第一个 table 中引用了一个参考。注意它是如何变化的。您没有索引 1-5,您有索引 0-4。

Table 1: [0][1][2][3][4]
Table 2: [0]

然后你的循环增加更多,你最终达到这一点:

Table 1: [0][1][2]
Table 2: [0][1][2]

现在当你到达索引 3 时,就没有了。如果您不关心顺序,您可以做的一件事是向下迭代,从行数开始并朝着 0 方向努力。

for (int i = gaTable.Rows.Count - 1; i >= 0; i--)
{
    teamoptionstable.Rows.Add(gaTable.Rows[i]);
}

这将允许您从第一个 table 的末尾获取并考虑索引的变化。但是,这显然会给您留下相反的 table。

如果您确实关心顺序,则需要重新创建所有新的行和单元格,然后将它们添加到您的第二个 table。 Here is a great answer 丹尼尔·戴森 (Daniel Dyson) 的方法可以做到这一点。我对它做了一些修改。这是未经测试的,所以请注意这一点。

protected HtmlTable CopyTable(HtmlTable copyFromTable)
{
    if (copyFromTable != null && copyFromTable.Rows.Count > 0)
    {
        var copyToTable = new HtmlTable();
        HtmlTableRow copyRow;
        HtmlTableCell copyCell;

        for (int i = 0; i < copyFromTable.Rows.Count - 1; i++)
        {
            copyRow = new HtmlTableRow();
            for (int j = 0; j < copyFromTable.Rows[i].Cells.Count - 1; j++)
            {
                copyCell = new HtmlTableCell();
                copyCell.InnerHtml = copyFromTable.Rows[i].Cells[j].InnerHtml;
                copyRow.Cells.Add(copyCell);
            }
            copyToTable.Rows.Add(copyRow);
        }

        return copyToTable;
    }

    return null;
}