简体   繁体   English

C#对于表中的每个循环?

[英]C# For each loop in a a table?

I'm trying to display various information with the help of a for each loop.我试图在每个循环的帮助下显示各种信息。 I've created a for each loop, that iterates through a list of item.我为每个循环创建了一个循环,它遍历项目列表。 In this list there is another list of items.在这个列表中有另一个项目列表。

As for now it's displayed like this:至于现在它是这样显示的: 在此处输入图片说明

My code is:我的代码是:

@foreach (Invoice invoice in ViewBag.Invoices)
{
    <table>
        <tr>
            <th>Customer</th>
            <th>Product</th>
            <th>Quantity</th>
            <th>Price</th>
            <th>Total Price</th>
        </tr>

        @foreach (OrderItem orderItem in invoice.OrderItems)
        {
        <tr>
            <td>@invoice.Customer.Firstname @invoice.Customer.Lastname</td>
            <td>@orderItem.Product.Title </td>
            <td>@orderItem.Quantity </td>
            <td>@orderItem.Product.Price </td>            
            <td>@orderItem.TotalPrice</td>
        </tr>
        }

        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td class="border-top">@invoice.TotalPrice</td>
        </tr>
    </table>
}

However, I don't want it to display the customers name twice.但是,我不希望它两次显示客户名称。 And I don't want to have the customer on its own row.而且我不想让客户在自己的行中。 Therefore I tried to put the starting tag along with the customer outside of the foreach loop, and instead ending the foreach loop with a <tr> tag.因此,我尝试将起始标记与客户一起放在 foreach 循环之外,而是使用<tr>标记结束 foreach 循环。 So it'd look like this:所以它看起来像这样:

@foreach (Invoice invoice in ViewBag.Invoices)
{
    <table>
        <tr>
            <th>Customer</th>
            <th>Product</th>
            <th>Quantity</th>
            <th>Price</th>
            <th>Total Price</th>
        </tr>

        <tr>
        <td>@invoice.Customer.Firstname @invoice.Customer.Lastname</td>

        @foreach (OrderItem orderItem in invoice.OrderItems)
        {
            <td>@orderItem.Product.Title </td>
            <td>@orderItem.Quantity </td>
            <td>@orderItem.Product.Price </td>            
            <td>@orderItem.TotalPrice</td>
        </tr>
        <tr>
        }


            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td class="border-top">@invoice.TotalPrice</td>
        </tr>
    </table>
}

UPDATED SOLUTION更新的解决方案

I followed the wise words of @Ed Plunkett and initialized a local string to null.我遵循了@Ed Plunkett 的明智之言,并将本地字符串初始化为 null。 The I created an if/else statement to check if the previous customer has been set, and initialized the value of the previous customer in the end of the loop.我创建了一个 if/else 语句来检查前一个客户是否已经设置,并在循环结束时初始化前一个客户的值。

@{string prevCust = null; }

@foreach (Invoice invoice in ViewBag.Invoices)
{
    <table>
        <tr>
            <th>Customer</th>
            <th>Product</th>
            <th>Quantity</th>
            <th>Price</th>
            <th>Total Price</th>
        </tr>

        @foreach (OrderItem orderItem in invoice.OrderItems)
        {
            <tr>
            @if (prevCust != invoice.Customer.Firstname + invoice.Customer.Lastname)
            {
                <td>@invoice.Customer.Firstname @invoice.Customer.Lastname</td>
            }
            else
            {
                <td></td>
            }

            <td>@orderItem.Product.Title </td>
            <td>@orderItem.Quantity </td>
            <td>@orderItem.Product.Price </td>
            <td>@orderItem.TotalPrice</td>
        </tr>

            prevCust = invoice.Customer.Firstname + invoice.Customer.Lastname;
        }

        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td class="border-top">@invoice.TotalPrice</td>
        </tr>
    </table>
}

I'd do it caveman style: Just make a local variable String prevCustomerName , initialize to null, and update it at the end of the loop block.我会这样做穴居人风格:只需创建一个局部变量String prevCustomerName ,初始化为 null,并在循环块的末尾更新它。 At the beginning of the loop block, if the new customer name is the same as prevCustomerName , don't insert it into the HTML for that row.在循环块的开头,如果新客户名称与prevCustomerName相同, prevCustomerName其插入到该行的 HTML 中。

I enjoyed your original code with </tr>\\n<tr> in the inner loop, but it took me a minute to figure out what you were doing, and Razor seems to be totally baffled.我很喜欢你在内部循环中使用</tr>\\n<tr>的原始代码,但我花了一分钟才弄清楚你在做什么,而 Razor 似乎完全被搞糊涂了。 And you still need to ugly it up with a special case to add an empty cell on non-first rows.而且您仍然需要使用特殊情况来丑化它,以在非第一行上添加一个空单元格。 If you're stuck putting in an if either way, do the caveman.如果你在任何一种方式中都被困住了, if做穴居人吧。

When resorting to iteration in a table, it's helpful (even for yourself, not just for razor or whatever view engine you are using) to keep it as structured and simple as possible.当在表中使用迭代时,保持它尽可能结构化和简单是有帮助的(即使对你自己,不仅仅是对 razor 或任何你正在使用的视图引擎)。

(the comments on your question should be enough explanation as to why this is a good idea) (对您的问题的评论应该足以解释为什么这是一个好主意)

try using multiple tr's per invoice to achieve your goals.尝试使用每个发票的多个 tr 来实现您的目标。 for example :例如 :

@foreach (Invoice invoice in ViewBag.Invoices)
{
    <table>
        <tr>
            <th>Customer</th>
            <th>Product</th>
            <th>Quantity</th>
            <th>Price</th>
            <th>Total Price</th>
        </tr>

        <tr>
          <td colspan="4">@invoice.Customer.Firstname @invoice.Customer.Lastname</td>
        </tr>

        @foreach (OrderItem orderItem in invoice.OrderItems)
        {
            <tr>
              <td>@orderItem.Product.Title </td>
              <td>@orderItem.Quantity      </td>
              <td>@orderItem.Product.Price </td>            
              <td>@orderItem.TotalPrice    </td>
            </tr>
        }

        <tr>
            <td colspan="4"></td>
            <td class="border-top">@invoice.TotalPrice</td>
        </tr>
    </table>
}

You could even resort to generating one table per invoice if that helps make things simpler for you.如果这有助于使事情变得更简单,您甚至可以诉诸于为每个发票生成一张表格。

Without being ASP-expert I suppose you have to handle the first row differently then the others :如果不是 ASP 专家,我想您必须以不同的方式处理第一行,然后其他行:

<tr>
  <td>@invoice.Customer.Firstname @invoice.Customer.Lastname</td>
  <td>@orderItem.Product.Title </td>
  <td>@orderItem.Quantity      </td>
  <td>@orderItem.Product.Price </td>            
  <td>@orderItem.TotalPrice    </td>
</tr>

Now handle the rest in the loop omitting the first (already handled) element:现在处理循环中的其余部分,忽略第一个(已经处理的)元素:

@foreach (OrderItem orderItem in invoice.OrderItems.Skip(1))
{
    <tr>
      <td/>
      <td>@orderItem.Product.Title </td>
      <td>@orderItem.Quantity      </td>
      <td>@orderItem.Product.Price </td>            
      <td>@orderItem.TotalPrice    </td>
    </tr>
}

A more generic approach would be using a for -loop with an index and check if you´re handling the first element:更通用的方法是使用带有索引的for循环并检查您是否正在处理第一个元素:

@for(int i = 0; invoice.OrderItems.Count; i++)
{
    <tr>
      <td>@(i != 0 ? invoice.Customer.Firstname + " " + invoice.Customer.Lastname : "")</td>
      <td>@invoice.OrderItems[i].Product.Title </td>
      <td>@invoice.OrderItems[i].Quantity      </td>
      <td>@invoice.OrderItems[i].Product.Price </td>            
      <td>@invoice.OrderItems[i].TotalPrice    </td>
    </tr>
}

However I´m not sure if this is even valid ASP-syntax.但是我不确定这是否是有效的 ASP 语法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM