开发者

How to group a C# list when being displayed in html page

开发者 https://www.devze.com 2022-12-07 18:07 出处:网络
string flowerList = string.Empty; foreach (var flower in Plants.Where(x => x.Status == PlantStatus.Active))
string flowerList = string.Empty;
foreach (var flower in Plants.Where(x => x.Status == PlantStatus.Active))
{
    flowerList = string.IsNullOrWhiteSpace(flowerList)
                 ? "<li>" + flower.Colour + " " + flower.Priority + " " + flower.Category + "</li>"
                 : flowerList + "<li>" + flower.Colour + " " + flower.Priority + " " + flower.Category+ "</li>" ;
}

I have the above code to display a C# list data data in a html page. How can i group my flowerList html out put by flower.Category.

For each Category, I would wish 开发者_如何转开发to have flower.Category as the group header and then under it list the related records.


The code is already using LINQ. Grouping in LINQ is performed by the GroupBy operator. It's not a good idea to put the query in the foreach clause though, even for simple queries. Modifying it becomes a lot harder.

This snippet groups by category and then generates the HTML string. Instead of concatenating strings though it uses a StringBuilder to avoid creating temporary strings.

var categories=Plants.Where(x => x.Status == PlantStatus.Active)
                 .GroupBy(x=>x.Category);

var builder=new StringBuilder();
foreach(var category n categories)
{
    builder.AppendFormat("<div>\n<h1>{0}</h1>\n", category.Key);
    foreach(var flower in category)
    {
        builder.AppendFormat("<li>{0} {1}</li>\n", 
                           flower.Colour, 
                           flower.Priority);
    }
    builder.AppendLine("</div>");
}

var html=builder.ToString();

Template Engines

Generating strings like this works only for simple HTML though. Even this code is becoming hard to maintain. In such cases it's better to use a template engine like Visual Studio's T4 or the more modern Scriban or Handlebars.NET.

The following example uses Scriban

var template = Template.Parse(@"
  <H1>Flowers by Category</H1>
  {{ for category in Categories }}
    <div>
       <h2>{{ category.key }}</h2>
       <ul>
       {{ for flower in category }}
           <li>{{ flower.Colour }} {{ flower.Priority }}</li>
       {{ end }} 
       </ul>
    </div>
  {{ end }}
");

var html = template.Render(new { Categories = categories });

It's now a lot easier to understand what the output will look like, edit the template and find any errors.

There are at least two Visual Studio Code extensions that offer syntax highlighting and autocompletion for Scriban templates: Scriban and SiteCore Scriban


Here is one possible way to group the output by flower.Category:

string flowerList = string.Empty;

// Group the flowers by category
var flowerGroups = Plants
    .Where(x => x.Status == PlantStatus.Active)
    .GroupBy(x => x.Category);

// Iterate over the groups and create the HTML output
foreach (var group in flowerGroups)
{
    // Create the header for the group
    flowerList += "<h3>" + group.Key + "</h3>";

    // Create a list of flowers in the group
    flowerList += "<ul>";
    foreach (var flower in group)
    {
        flowerList += "<li>" + flower.Colour + " " + flower.Priority + " " + flower.Category + "</li>";
    }
    flowerList += "</ul>";
}

This code will first group the flowers by flower.Category, then iterate over the groups and create a heading for each group followed by a list of flowers in that group. The final result will be a string containing the HTML output.


var categories=Plants.Where(x => x.Status == PlantStatus.Active) .GroupBy(x=>x.Category);

var builder=new StringBuilder("

    "); foreach(var plants in categories) { foreach(var plant in plants) { builder.AppendFormat("
  • {0} {1} {2}
  • \n", flower.Colour, flower.Priority, flower.Category); } } builder.AppendLine("
");

var html=builder.ToString();

0

精彩评论

暂无评论...
验证码 换一张
取 消