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;
}
我在我的代码隐藏中创建了两个 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;
}