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

时间:2013-05-31 23:47:13

标签: c# list struct messagebox

我正在开展一个项目,需要显示收入高于平均水平的人员名单。源数据为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>();

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

//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]其中的ID和收入高于平均水平的人应该是。有人可以告诉我我做错了什么以及如何在消息框中显示列表值?

3 个答案:

答案 0 :(得分:0)

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做,你想看到吗?

好的,这是一个性感的单行版本:(所有问题应该有一行linq答案):

(使用和缩进不计算,它们只是为了使代码更具可读性!)

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.");

答案 1 :(得分:0)

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

然后,您需要为自定义结构定义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.Show调用中,您需要用

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

应该让它正确显示。

抱歉格式化,我在移动设备上。

答案 2 :(得分:0)

在问题的最后,您问:如何在消息框中显示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());

请参阅以下内容(和online demo),了解其预期输出之前的完整工作示例。

预期输出

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);
            }
        }
    }
}