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();
精彩评论