如何在消息框中显示列表中的项目

本文关键字:显示 列表 项目 消息 | 更新日期: 2023-09-27 18:16:16

我正在研究一个需要显示收入高于平均水平的人的列表的项目。源数据是List<IncomeData> (id是人员的唯一id):

public struct IncomeData
{
    public string id;
    public double household;
    public income;
}
public double belowAverage = 0, total, belowAveragePercent;
IncomeData surveyStruct;
List<IncomeData> surveyList = new List<IncomeData>();
List<string> aboveAverage = new List<string>();

下面是我如何判断一个人的收入是否高于平均水平。如果一个人的收入高于平均水平,我将surveyStruct的临时实例中的idincome添加到上述字符串值的平均列表中:

//Determine poverty.
if (surveyStruct.income - 3480 * surveyStruct.household <= 6730)
{
    belowAverage += 1;
}
else if (surveyStruct.income - 3480 * surveyStruct.household >= 6730)
{
    aboveAverage.Add(surveyStruct.id);
    aboveAverage.Add(surveyStruct.income.ToString());
}

下面是在消息框中显示所需信息的代码。(这里也添加了aboveAverage列表)

private void reportsToolStripMenuItem_Click(object sender, EventArgs e)
{
    //Display reports 1, 2, and 3.
    MessageBox.Show("Your Entry:'nID Code: " + surveyStruct.id +
       "'nHousehold: " + surveyStruct.household.ToString() +
       " people'nIncome: " + surveyStruct.income.ToString("C") +
       "'n'nPeople Above Average:'n" + aboveAverage +
       "'n'nAnd " + belowAveragePercent + "% of people are below average.");
    }

现在,问题来了:而不是在消息框中看到值列表,我看到的是System.Collections.Generic.List `1[System.String]为上述一般人的身份证和收入。有人能告诉我我做错了什么,以及如何在消息框中显示列表值吗?

如何在消息框中显示列表中的项目

在您的问题结束时,您问:我如何在消息框中显示List<IncomeData> ?

所以,你问题的核心是将你的值列表转换为字符串,以便你可以将该字符串作为参数传递给MessageBox.Show()

LINQ扩展方法Enumerable.Aggregate()为这个问题提供了一个理想的解决方案。假设您的List<IncomeData>看起来像这样(为了简洁,我省略了household字段):
var incomes = new List<IncomeData>() {
    new IncomeData("abc0123", 15500),
    new IncomeData("def4567", 12300),
    new IncomeData("ghi8901", 17100)
};

以下LINQ查询将把List<IncomeData>转换成string:

string message = incomes.
    Select(inc => inc.ToString()).
    Aggregate((buffer, next) => buffer + "'n" + next.ToString());

为了消除调用Select()的需要,您可以使用Enumerable.Aggregate()的双参数版本。这种方法还允许您指定一个标题作为累加器的种子值:

string message2 = incomes.
    Aggregate(
        "Income data per person:",
        (buffer, next) => buffer + "'n" + next.ToString());

这相当于下面的参数类型已经明确:

string message = incomes.
    Aggregate<IncomeData, string>(
        "Income data per person:",
        (string buffer, IncomeData next) => buffer + "'n" + next.ToString());

请参阅以下(和在线演示),以获得完整的工作示例,前面是预期的输出。

预期输出

Income data per person:
Id: abc0123, Income:15500
Id: def4567, Income:12300
Id: ghi8901, Income:17100
示范项目

using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqAggregateDemo
{
    public class Program
    {
        public static void Main(string[] args)
        {            
            var incomes = new List<IncomeData>() {
                new IncomeData("abc0123", 15500),
                new IncomeData("def4567", 12300),
                new IncomeData("ghi8901", 17100)
            };
            string message = incomes.
                Select(inc => inc.ToString()).
                Aggregate((buffer, next) => buffer + "'n" + next.ToString());
            Console.WriteLine("Income data per person:'n" + message);
        }
        public struct IncomeData
        {
            public readonly string Id;
            public readonly int Income;
            public IncomeData(string id, int income)
            {
                this.Id = id;
                this.Income = income;
            }
            public override string ToString()
            {
                return String.Format(
                    "Id: {0}, Income:{1}",
                    this.Id,
                    this.Income);
            }
        }
    }
}

首先,将aboveAverage设置为List<IncomeData>,并将匹配的incomedata添加到该列表中。

然后,您需要为您的自定义结构定义一个ToString,如下所示:
public override void string ToString()
{
  return string.Format("The id is {0}, the household is {1} and the income is {2}.", id, household, income);
}

然后,在您的MessageBox中。显示调用,你需要用

替换aboveAverage
aboveAverage.Aggregate((a,b) => a.ToString() + Enviroment.NewLine + b.ToString())

应该能正常显示。

很抱歉格式不对,我在用手机。

StringBuilder是一个选择:

    StringBuilder aboveAverage = new StringBuilder();
    //Determine poverty.
     if (surveyStruct.income - 3480 * surveyStruct.household <= 6730)
    {
        belowAverage += 1;
    }
    else if (surveyStruct.income - 3480 * surveyStruct.household >= 6730)
    {
        aboveAverage.Append(string.Format("id: %s, income: %s'n",
                surveyStruct.id, surveyStruct.income.ToString());
    }

您将需要一个ToString()用于字符串构建器,如下所示:

    MessageBox.Show("Your Entry:'nID Code: " + surveyStruct.id + "'nHousehold: " + surveyStruct.household.ToString() + " people'nIncome: " + surveyStruct.income.ToString("C") + "'n'nPeople Above Average:'n" + aboveAverage.ToString() + "'n'nAnd " + belowAveragePercent + "% of people are below average.");

如果你把aboveAverage作为一个列表,你可以用join来做,像这样:

 string.Join(aboveAverage,Environment.NewLine);

在你当前的代码中——但这看起来不太好。

你也可以用Linq来做,你想看吗?

好吧,这是一个性感的一行版本:(所有的问题都应该有一个一行的回答):

(using和缩进不算数,它们只是为了让代码更容易读!)

using NL = Environment.NewLine;
    
string indent = "    ";
MessageBox.Show(
  "Your Entry:" + NL +
  "ID Code: " + surveyStruct.id +  NL +
  "Household: " + surveyStruct.household.ToString() + " people" + NL +
  "Income: " + surveyStruct.income.ToString("C") + NL + NL +
  "People Above Average:"  + NL +
     indent + string.Join(NL+indent,
                          surveyList.Where(s => (s.income - 3480) * s.household >= 6730)
                                    .Select(s => "ID: "+s.id+" $"+s.income.ToString).ToArray()) + NL +
         "And " + (surveyList.Where(s => ((s.income - 3480) * s.household) <= 6730).Count() / surveyList.Count()) * 100 + "% of people are below average.");