【问题标题】:c# - Reading a complex file into a comboBoxc# - 将复杂文件读入组合框
【发布时间】:2015-02-21 00:55:51
【问题描述】:

所以我尝试了一些研究,但我只是不知道如何用谷歌搜索这个..

例如,我有一个 .db(对我来说与 .txt 相同)文件,这样写:

DIRT: 3;
STONE: 6;

到目前为止,我得到了一个可以将项目放入组合框中的代码,如下所示:

DIRT,
STONE,

会将 DIRT 和 STONE 放入组合框中。这是我正在使用的代码:

        string[] lineOfContents = System.IO.File.ReadAllLines(dbfile);
        foreach (var line in lineOfContents)
        {
            string[] tokens = line.Split(',');
            comboBox1.Items.Add(tokens[0]);
        }

我如何扩展它,以便它放置例如组合框中的 DIRT 和 STONE,并将其余 (3) 保留在变量中(整数,如 int varDIRT = 3)? 如果你愿意,它不一定是 txt 或 db 文件。我听说 xml 也是配置文件。

【问题讨论】:

  • 尝试创建一个类来保存该信息。用逗号分割没有意义,因为在您的示例数据中,您没有显示任何逗号。你的意思是:冒号?
  • A ComboBox 有两个可以使用的属性。一个是ValueMember,一个是DisplayMember。例如,您可以将 db 文件读入具有两列的表中,elementvalue 或其他内容。然后将ValueMember 设置为value 并将DisplayMember 设置为element。当然,您还必须确保将ComboBox 的数据源设置为包含您的数据的表。
  • @LarsTech 在我以前的数据库文件中,我有逗号,这就是它仍然存在的原因。对于新的,我当然必须使用分号。这让我想到了一个想法:如果我在双点的东西上有分行,我还能以某种方式阅读其余的行吗?

标签: c# database file-io combobox file-read


【解决方案1】:

尝试做这样的事情:

            cmb.DataSource = File.ReadAllLines("filePath").Select(d => new
            {
                Name = d.Split(',').First(),
                Value = Convert.ToInt32(d.Split(',').Last().Replace(";",""))
            }).ToList();
            cmb.DisplayMember = "Name";
            cmb.ValueMember= "Value";

记住它需要使用using System.Linq; 如果您想引用组合框的选定值,您可以使用 cmb.SelectedValue; cmb.SelectedText;

【讨论】:

  • 我收到一个错误,...Forms.ComboBox 不包含“DataMember”的定义并且没有扩展方法“DataMember”...等等。价值也一样。
  • OP 发布的示例数据不是逗号分隔的。您可能希望使用 ':' 进行拆分并删除 ';'在转换值之前。
  • 你是在正确的Delimiter上分裂吗?这是他的数据的样子DIRT: 3;
  • 我会尝试自己修复错误的拆分问题,但是谢谢,我认为这是一个 ncie 解决方案。投我一票!
  • 我使用昏迷是因为在他的代码中他使用的是line.Split(',')所以我不确定哪个是哪个
【解决方案2】:

我认为您确实有两个问题,所以我将尝试分别回答。

第一个问题是“我怎样才能解析一个看起来像这样的文件...

DIRT: 3;
STONE: 6;

到名称和整数?”你可以从每一行中删除所有的空格和分号,然后在冒号上拆分。在我看来,更简洁的方法是使用正则表达式:

// load your file
var fileLines = new[]
{
    "DIRT: 3;",
    "STONE: 6;"
};

// This regular expression will match anything that
// begins with some letters, then has a colon followed
// by optional whitespace ending in a number and a semicolon.
var regex = new Regex(@"(\w+):\s*([0-9])+;", RegexOptions.Compiled);
foreach (var line in fileLines)
{
    // Puts the tokens into an array.
    // The zeroth token will be the entire matching string.
    // Further tokens will be the contents of the parentheses in the expression.
    var tokens = regex.Match(line).Groups;
    // This is the name from the line, i.e "DIRT" or "STONE"
    var name = tokens[1].Value;
    // This is the numerical value from the same line.
    var value = int.Parse(tokens[2].Value);
}

如果您不熟悉正则表达式,我鼓励您检查一下;它们使格式化字符串和提取值变得非常容易。 http://regexone.com/

第二个问题,“如何在名称旁边存储值?”,我不确定我是否完全理解。如果您要做的是用文件中指定的数值返回每个项目,dub stylee 的建议对您有好处。您需要将 name 作为显示成员,将 value 作为值成员。但是,由于您的数据不在表中,因此您必须将数据放在可访问的位置,以便可以命名您要使用的属性。我推荐一本字典:

        // This is your ComboBox.
        var comboBox = new ComboBox();

        // load your file
        var fileLines = new[]
        {
            "DIRT: 3;",
            "STONE: 6;"
        };

        // This regular expression will match anything that
        // begins with some letters, then has a colon followed
        // by optional whitespace ending in a number and a semicolon.
        var regex = new Regex(@"(\w+):\s*([0-9])+;", RegexOptions.Compiled);

        // This does the same as the foreach loop did, but it puts the results into a dictionary.
        var dictionary = fileLines.Select(line => regex.Match(line).Groups)
            .ToDictionary(tokens => tokens[1].Value, tokens => int.Parse(tokens[2].Value));

        // When you enumerate a dictionary, you get the entries as KeyValuePair objects.
        foreach (var kvp in dictionary) comboBox.Items.Add(kvp);

        // DisplayMember and ValueMember need to be set to
        // the names of usable properties on the item type.
        // KeyValue pair has "Key" and "Value" properties.
        comboBox.DisplayMember = "Key";
        comboBox.ValueMember = "Value";

在这个版本中,我使用了 Linq 来构建字典。如果您不喜欢 Linq 语法,可以使用循环代替:

var dictionary = new Dictionary<string, int>();
foreach (var line in fileLines)
{
    var tokens = regex.Match(line).Groups;
    dictionary.Add(tokens[1].Value, int.Parse(tokens[2].Value));
}

【讨论】:

  • 很好,但是对于“第一个问题”,拆分后如何读取文件的其余部分?
  • @devRicher 如果您希望您的文件包含 DIRT:3 中没有的其他内容;格式,那么您需要使用正则表达式来测试行 is 是否匹配。如果是,那么您可以像我一样使用已解析的令牌。如果不是,您将执行其他操作。
【解决方案3】:

您也可以使用 FileHelpers 库。首先定义你的数据记录。

[DelimitedRecord(":")]
public class Record
{
  public string Name;
  [FieldTrim(TrimMode.Right,';')]
  public int Value;    
}

然后你像这样读入你的数据:

FileHelperEngine engine = new FileHelperEngine(typeof(Record));
//Read from file
Record[] res = engine.ReadFile("FileIn.txt") as Record[];

// write to file
engine.WriteFile("FileOut.txt", res);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-30
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 2017-06-07
    相关资源
    最近更新 更多