我正在编写一个简单的程序,将输入写入顺序访问文件,然后将其读回并使用.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
答案 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
块将您的呼叫替换为Catch
。 File.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而不是列表框。我认为你不能与列表框项目正确对齐。