找到用于编写HTML表的foreach中组的最后一行

本文关键字:最后 一行 用于 HTML foreach 表的 | 更新日期: 2023-09-27 18:18:32

我有一个问题在我的asp.net (c#)代码,让我的foreach循环做一个特定的事情,当它达到一个新的行输入从我的数据库;一个简单的例子:

我有我的数据库抛出5组行:

       column
row1 | ca     
row2 | ca
row3 | ro
row4 | ro
row5 | ef

我将这些行放入foreach循环中,并将它们循环到HTML表中。这样我想要一个border-bottom,就在每次它进入一个新的行"集合"之前。如果可能的话,我希望一切都是动态的。

我希望我的表在得到输出时是这样的:

<table>
 <tr><td>ca</td></tr>
 <tr style='border-bottom: 1px solid Red'><td>ca</td></tr>
 <tr><td>ro</td></tr>
 <tr style='border-bottom: 1px solid Red'><td>ro</td></tr>
 <tr style='border-bottom: 1px solid Red'><td>ef</td></tr>
</table>

我只是想补充一点,我对整个c#世界和编程都很陌生,但我正在学习并喜欢它:)-我希望你们能帮助我…如果有什么不清楚的地方就说出来,我会尽量详细说明的。

foreach (DataRow row in dt.Rows) {
 //HERE I WANT MY TR TO HAVE A BORDER BOTTOM WHEN IT REACHES A NEW SET OF ROW
 if (row["colLink"].ToString() != "") {
  litTilbud.Text += "<tr onClick='window.open('"" + row["colLink"] + "'", '"_blank'")' style='cursor: pointer;'>";
 } else {
  litTilbud.Text += "<tr>";
 }
 litTilbud.Text +=  "<td class='tooltip' title='" + row["colDok"] + " - Tilføjet af: " + row["colNavn"] + "'>" + row["colSodavand"] + "</td>";
 litTilbud.Text +=  "<td>" + row["colAntal"] + " " + row["colType"] + " a " + row["colStorrelse"] + "L</td>";
 litTilbud.Text +=  "<td><strong>" + string.Format("{0:#.00}", row["colPris"]) + ",-</strong></td>";
 litTilbud.Text +=  "<td>(" + string.Format("{0:#.00}", row["Literpris"]) + ",-)</td>";
 litTilbud.Text +=  "<td>" + row["colSupermarked"] + "</td>";
 litTilbud.Text += "</tr>";
}

找到用于编写HTML表的foreach中组的最后一行

我认为你不需要foreach循环。相反,尝试使用RepeaterGridView。然后你所需要做的就是绑定你的数据(你的数据库输出),你就完成了。

我建议查找一些如何使用它的示例。这需要一点学习,但它给了你更多的控制,使你的代码更容易理解。

一个简化的例子,编辑它以适应您的需要:

<asp:GridView ID="MyGrid" runat="server" CssClass="MyGridStyle"
    OnRowDataBound="MyGrid_OnRowDataBound"
    AutoGenerateColumns="false">
    <Columns>
        <asp:BoundField DataField="yourDataField" />
    </Columns>
</asp:GridView>
在后面的代码中,放置一个事件处理程序,如下所示:
protected void MyGrid_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    // only datarows, no header rows:
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // user e.Row.DataItem to get to the data
        if(your logic here about groups)
        {
             e.Row.Style = "border-bottom:solid black 1px";
        }
    }
}

Page_Load中,您可以添加以下代码来绑定GridView与您的数据:

MyGrid.DataSource = YourObjectWithDataFromDatabase;
MyGrid.DataBind();   // bind data to gridview

注意:如果你的数据源有你想要的字段,不多不少,你可以设置AutoGenerateColumnstrue,并删除Columns -定义,这使你的代码更容易。

如果可以使用索引而不是foreach进行迭代,可能会更容易。假设您的集合可以通过索引访问(我认为这是一个相当安全的假设)。它可能看起来像:

 for (int i =0; i < collection.Count - 1; ++i)
 {
      var row = // create a new row
      string current = collection[i];
      string next = collection[i+1];
      if (current != next)
      {
           // add a "lastitem" class or set the style directly
      }
 }
 if (collection.Count > 0)
 {
     // build the last row with "lastitem" class (or setting style directly)
 }

你会注意到,我掩盖了构建行,因为你没有指定如果你使用WebForms和正在构建的行作为文本(不是一个特别好的主意)或HTML元素(更好),或正在使用ASP。. NET MVC和直接在视图中构建行(最佳选择,IMO)。

另外,我认为你最好使用CSS类,如"lastitem",而不是直接在元素上设置样式。你的代码会更清晰,如果你决定以不同的方式显示东西,你需要做的就是改变你的CSS文件,而不是重写你的代码。

.lastitem {
    border-bottom: 1px solid #ff0000;
}

我建议添加一个列到您的数据集与一个标志,指定是否需要在html中做装饰。然后你所需要做的就是写一个循环。它看起来像这样:

StringBuilder sb = new StringBuilder;
sb.Append("<table>");
foreach(var row in rowsCollection) 
{
   if(row.NeedsDecoration) 
   {
       sb.Append(" <tr style='border-bottom: 1px solid Red'><td>");
   } else sb.Append("<tr><td>");
   sb.Append(row.YourField);
   sb.Append("</td></tr>");
}
sb.Append("</table>");
return sb.ToString();

下面是一些帮助您开始使用ADO的代码。从数据库中检索数据并将其存储在DataTable中。这是未经测试的代码,但是您将得到一般的逻辑流。

public void GetDataAndDisplay()
{
    DataTable myData = new DataTable();
    myData = GetDataFromDb();
    LoopThroughTable(myData);
}
public DataTable GetDataFromDb()
{
    // you can also stored your connection string in the web.config file
    //  and utilize ConfigurationManager class
    SqlConnection dbConn = new SqlConnection("your connectionstring here");
    SqlCommand GetData = new SqlCommand();
    GetData.Connection = dbConn;
    GetData.CommandText = "select col1, col2 from yourTable";
    SqlDataAdapter dataAdapter = new SqlDataAdapter(GetData);
    DataTable YourData = new DataTable();
    try
    {
        dataAdapter.Fill(YourData);
    }
    catch (Exception ex)
    {
        // do something
    }
    return YourData;
}
public void LoopThroughTable(DataTable dataTable)
{
    foreach(DataRow row in dataTable.Rows)
    {
        // construct your html strings here...
    }
}

毫无疑问,最好的办法是利用第三方控件(甚至是asp.net内置控件之一),让它为你处理这些问题。也就是说,我能想到的最好的方法就是使用LINQ。

的例子

如果您创建一个新的WebForm页面,并将以下内容粘贴到其中(在代码后面,.aspx.cs文件中)(我将在后面解释这一切的作用):

private DataTable GetData()
{
    var result = new DataTable();
    result.Columns.Add("ColumnToGroupBy", typeof(string));
    result.Columns.Add("AnotherColumn", typeof(int));
    result.Columns.Add("YetAnotherColumn", typeof(string));
    result.Rows.Add(new object[] { "ca", 3, "abc" });
    result.Rows.Add(new object[] { "ca", 4, "cake" });
    result.Rows.Add(new object[] { "ro", 8, "apple" });
    result.Rows.Add(new object[] { "ro", 1, "pair" });
    result.Rows.Add(new object[] { "ef", 2, "okra" });
    return result;
}
protected void Page_Load(object sender, EventArgs e)
{
    var data = GetData();
    var groupedData = from row in data.AsEnumerable()
                        group row by row.Field<string>("ColumnToGroupBy") into grouping
                        select grouping;
    foreach (var group in groupedData)
    {
        TableRow row = null;
        foreach (var item in group)
        {
            row = new TableRow();
            row.Cells.Add(new TableCell() { Text = item.Field<string>("ColumnToGroupBy") });
            row.Cells.Add(new TableCell() { Text = item.Field<string>("YetAnotherColumn") });
            myTable.Rows.Add(row);
        }
        row.CssClass = "CssClassThatSetsTheBottomBorder";
    }
}

然后在主标记(.aspx文件)中放入以下内容,替换Visual Studio为您创建的等效标记:

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css" media="screen">
        .CssClassThatSetsTheBottomBorder
        {
            /* I've used a background colour as it's more obvious */
            background-color: Red;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:Table runat="server" ID="myTable">
    </asp:Table>
    </div>
    </form>
</body>
</html>

这个例子的第一个块基本上有一个叫做"GetData"的方法,它在那里假装是你的数据库。有趣的事情发生在第二部分:

var groupedData = from row in data.AsEnumerable()
                    group row by row.Field<string>("ColumnToGroupBy") into grouping
                    select grouping;

这所做的是根据ColumnToGroupBy列中的值,将您拥有的所有数据行放入中,因此我们有ca组,ro组和ef组。然后代码依次获取每个组并将每一行写到表中(我使用了asp.net WebForms内置的table/TableRow/TableCell,而不是自己编写HTML)。因为我们循环遍历每个组,然后遍历每个组中的每个项目,一旦我们完成了组中的最后一个项目,我们就可以将其Css样式设置为底部边框。这就是row.CssClass = "CssClassThatSetsTheBottomBorder";行所做的。

试一试代码,玩一玩它,它应该是有意义的=)