格式化.readLine输出为货币和右对齐

时间:2014-04-14 17:33:12

标签: vb.net

我正在编写一个简单的程序,将输入写入顺序访问文件,然后将其读回并使用.readLine在列表框中显示它们。这些数字需要格式化为美国货币并且右对齐。问题是我无法弄清楚如何正确编写.readLine来做到这一点。 我正在编写一本教科书,并且仍然是vb.net的新手,所以我正在寻找解决这个问题的最简单方法,而无需重新编写它。 我有的代码尝试在下面的DO循环中:

Private Sub btnDisplay_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click
    'declare new inFile Varable as a streamreader object
    Dim inFile As IO.StreamReader
    'opens gross.txt for input
    inFile = IO.File.OpenText("gross.txt")
    '.Exists() searches /bin folder for gross.txt, returns a boolean value
    If IO.File.Exists("gross.txt") Then
        inFile = IO.File.OpenText("gross.txt")
        'fill the list with the values
        Do Until inFile.Peek = -1
            lstContents.Items.Add(inFile.ReadLine.PadLeft(7, " ")).ToString("C2")
        Loop
    Else
        MessageBox.Show("The file you have requested does not exist", "Gross Pay Project",
                        MessageBoxButtons.OKCancel, MessageBoxIcon.Error)
    End If
End Sub

2 个答案:

答案 0 :(得分:3)

我们可以将其归结为一行:

lstContents.Items.AddRange(File.ReadAllLines("gross.txt").Select(Function(s) Double.Parse(s).ToString("C2").PadLeft(7)).ToArray())

或者以更易读的方式,错误处理和方法定义:

Private Sub btnDisplay_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click
    Try
        lstContents.Items.AddRange( _
            File.ReadAllLines("gross.txt").
                    Select(Function(s) Decimal.Parse(s).ToString("C2").PadLeft(7)).
                    ToArray()  )
    Catch ex As IOException
         MessageBox.Show("Unable to open the file you requested", "Gross Pay Project",
                        MessageBoxButtons.OKCancel, MessageBoxIcon.Error)
    End Try
End Sub

现在解释一下这段代码。首先,我使用IO.File.Exists() / Try块将您的呼叫替换为CatchFile.Exists()仅检查文件可能无法打开的一个原因。它忽略了文件权限和进程锁定等其他原因。即使检查文件是否存在,文件系统仍然是易失性的,并且您仍然存在竞争条件情况,当您检查文件是否存在以及何时打开文件时,文件可能会被删除。如果打开文件失败,只需完全跳过调用File.Exists()并使用try / catch块来处理异常几乎总是更好,如上所示。

进入Try / Catch块,我更改了代码,使其使用AddRange()而不是在循环中一次添加一个项目。这允许我们使用我们想要的项目构建一个数组,并在一个步骤中更新UI。构建该数组似乎是额外的工作,但.Net提供了一些功能来帮助我们。在这种情况下,File.ReadAllLines()方法一步读入整个文件,以便我们可以从一开始就使用数组。我们所要做的就是让阵列拥有正确的信息。

要获取数组中所需的信息,我执行现有数据的投影转换。为了实现这一点,我使用了LINQ select运算符(或者.Select()扩展方法,在本例中)。 LINQ扩展方法通常要求您构建内联函数。在使用select运算符的情况下,该内联函数需要一个表示原始数组中单行的字符串变量(s)。然后我提供代码将原始字符串转换为我们需要的格式。

文件中的每一行都以字符串值开头,但我们知道字符串变量包含定价信息......它将是数字。转换数字数据的最佳方法通常是将数字转换为数字,这就是我所做的。我选择Decimal类型,因为在使用金钱时,您几乎总是希望将Decimal优于Double或Single。在这种情况下,Double可能没问题,但Decimal仍然可以正常工作。一旦我有像Decimal这样的数字类型,我可以使用Numeric Format String来获取具有正确货币符号和格式的字符串。原始代码不起作用,因为您尝试使用格式字符串,其值已经是字符串类型。格式字符串仅适用于数字类型,如我们这里的Decimal。现在我有一个包含正确文本的字符串,我现在需要做的就是填充它,以便在列表中显示时它是右对齐的。

最后,您会记得AddRange()方法需要一个数组。 LINQ select运算符不生成数组。它产生一种称为IEnumerable的东西。这是一种表示某种序列的类型。数组是一种序列,但它们不是唯一的类序列,LINQ系统希望能够处理许多不同类型的序列。值得庆幸的是,回到数组很简单:只需调用ToArray()方法。

答案 1 :(得分:0)

您绝对应该使用ListView而不是列表框。我认为你不能与列表框项目正确对齐。