基本上,我让用户打开一个当前格式为这样的文本文档。
然后,它将信息拆分为数组,然后拆分汉堡.jpg,双下肯德基,食品,30/06/95,这是一个汉堡
为变量,然后拆分为文本框。
显然,如果我想要多条记录,我可能不得不以不同的方式格式化它,(这就是我需要帮助的)
但是,如果我有这样的记录,那么从文本文件中获取这些记录并将它们单独存储以便我可以轻弹它们的最有效方法是什么。例如,在我的表单上有一个组合框。选择记录后,窗体将填充该记录数据。
多条记录:
汉堡.jpg,双下肯德基,食品,30/06/95,这是一个汉堡
人.jpg,微笑,人,23/06/95,这是一个人
这是我目前这部分的代码。
private void LoadFile()
{
StreamReader reader = new StreamReader(fileName);
content = reader.ReadLine();
doc = content.Split(',');
filename = Convert.ToString(doc[0]);
fileNameTextBox.Text = doc[0];
description = doc[1];
descriptionTextBox.Text = doc[1];
category = doc[2];
categoryComboBox.Text = doc[2];
//dateTaken = Convert.ToDouble(doc[3]);
dateTakenTextBox.Text = doc[3];
comments = doc[4];
commentsTextBox.Text = doc[4];
}
这段代码目前有效,但仅适用于第一条记录,因为它使用一个数组,我显然需要多种方法来存储其他行。
我认为,如果我要给它一个猜测,最好的选择是将某种列表与生成记录的类一起使用,但这就是我陷入困境并需要帮助的地方。(通常我在这里的问题会被否决,因为如果是这种情况,我不够简洁,我会尝试改变我的问题。
谢谢大家。
我会创建一个保存记录信息的类
public class ImageInfo
{
public string FileName { get; set; }
public string Description { get; set; }
public string Category { get; set; }
public DateTime Date { get; set; }
public string Comments { get; set; }
public override string ToString()
{
return FileName;
}
}
现在你可以编写一个返回图像信息的方法
public List<ImageInfo> ReadImageInfos(string fileName)
{
string[] records = File.ReadAllLines(fileName);
var images = new List<ImageInfo>(records.Length);
foreach (string record in records) {
string[] columns = record.Split(',');
if (columns.Length >= 5) {
var imageInfo = new ImageInfo();
imageInfo.FileName = columns[0];
imageInfo.Description = columns[1];
imageInfo.Category = columns[2];
DateTime d;
if (DateTime.TryParseExact(columns[3], "dd/MM/yy",
CultureInfo.InvariantCulture, DateTimeStyles.None, out d))
{
imageInfo.Date = d;
}
imageInfo.Comments = columns[4];
images.Add(imageInfo);
}
}
return images;
}
现在,您可以像这样用这些记录之一填充文本框
List<ImageInfo> images = ReadImageInfos(fileName);
if (images.Count > 0) {
ImageInfo image = images[0];
fileNameTextBox.Text = image.FileName;
descriptionTextBox.Text = image.Description;
categoryComboBox.Text = image.Category;
dateTakenTextBox.Text = image.Date.ToShortDateString();
commentsTextBox.Text = image.Comments;
}
此方法的优点是读取和显示记录这两个操作是分开的。这样可以更轻松地理解和修改代码。
如果重写 ImageInfo
类中的 ToString
方法,则可以直接将ImageInfo
对象添加到ComboBox
或ListBox
,而不是添加文件名。
public override string ToString()
{
return FileName;
}
将项目添加到组合框中,如下所示:
myComboBox.Items.Add(image); // Where image is of type ImageInfo.
您可以使用以下命令检索当前选定的项目:
ImageInfo image = (ImageInfo)myComboBox.SelectedItem;
您很可能会在 SelectedIndexChanged
事件处理程序中执行此操作。
void myComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
ImageInfo image = (ImageInfo)myComboBox.SelectedItem;
myTextBox.Text = image.FileName;
}
创建一个类似于一行数据的类,然后遍历该文件,进行拆分并使用拆分数据构造新的类实例。将其存储在 List<>(或其他一些适当的结构)中,确保存储它以便以后可以引用它。不要在加载和分析文件时更改您的 UI(正如 Mike 所建议的那样),正如 Mike 建议的那样,您需要阅读直到达到 EOF(网络上有很多这方面的示例)MSDN 示例。
此外,流读取器实现 IDisposable,因此您需要释放它,或将其包装在 using 语句中以进行清理。
示例类,您甚至可以将该行作为构造函数参数传入:
public class LineItem
{
public string FileName { get; set; }
public string Description { get; set; }
public string Category { get; set; }
public DateTime DateTaken { get; set; }
public string Comments { get; set; }
public LineItem(string textRow)
{
if (!string.IsNullOrEmpty(textRow) && textRow.Contains(','))
{
string[] parts = textRow.Split(',');
if (parts.Length == 5)
{
// correct length
FileName = parts[0];
Description = parts[1];
Category = parts[2];
Comments = parts[4];
// this needs some work
DateTime dateTaken = new DateTime();
if (DateTime.TryParse(parts[3], out dateTaken))
{
DateTaken = dateTaken;
}
}
}
}
}
您的代码不会循环访问文件中的记录。
您希望继续阅读,直到文件结束。
while (content != eof)
{
// split content
// populate text boxes
}
但这会在循环的每次传递时覆盖您的文本框。此外,您希望分离代码 - 不要将 I/O 进程与更新 UI 的代码混合使用。该方法的名称意味着您正在加载文件,但该方法的作用远不止于此。 我建议更改读取文件的方法,将每条记录拆分为一个类对象,然后将其存储到数组中 - 并返回该数组。
一个单独的方法将采用该数组并填充表或网格或 UI 中的任何内容。 理想情况下,您将网格视图绑定到数组。
如果您保持所有条目相同:
name,food,type,blah blah
name,food,type,blah blah
您可以在代码中添加另一个拆分:
line = content.Split('n');
foreach (line in filename)
{
doc = line.Split(',');
//do stuff...
至于字符串多个条目的选项,我使用的一种方法是实现模型列表:
class ModelName
{
string Name { get; set; }
string foodType { get; set; }
//etc...
public void ModelName()
{
Name = null;
foodType = null;
//etc...
}
}
List<Model> ModelList;
foreach (line in filename)
{
doc = line.Split(',');
Model.Name = doc[1];
//etc...
并且对于每种类型的条目(人或食物)都有不同的列表和不同的模型