簡體   English   中英

如何在消息框中顯示列表中的項目?

[英]How do you display items from a list in a message box?

我正在做一個項目,該項目需要顯示一個收入高於平均水平的人的清單。 源數據是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]應該位於上面普通人的ID和收入所在的位置。 有人可以告訴我我做錯了什么以及如何在消息框中顯示列表值嗎?

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

如果您將average作為列表保留,則可以使用join來完成此操作,如下所示:

 string.Join(aboveAverage,Environment.NewLine);

在您當前的代碼中-但這看起來不太好。

您也可以使用Linq進行操作,想要看到嗎?

好的,這是一個性感的單行版本:(所有問題都應有一行linq答案):

(using和indent不計算在內,它們只是在使代碼更具可讀性!)

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

首先,在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())

應該使其正確顯示。

對不起格式,我在移動設備上。

在您問題的結尾,您會問: 如何在消息框中顯示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);
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM