devRicher
devRicher

Reputation: 458

c# - Reading a complex file into a comboBox

So I tried some research, but I just don't know how to google this..

For example, I got a .db (works same as .txt for me) file, written like this:

DIRT: 3;
STONE: 6;

so far, i got a code that can put items in a comboBox like this:

DIRT,
STONE,

will put DIRT and STONE in the comboBox. This is the code I'm using for that:

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

How do I expand this so it put e.g. DIRT and STONE in the combobox, and keep the rest (3) in variables (ints, like int varDIRT = 3)? If you want, it doesn't have to be txt or db files.. i heard xml are config files too.

Upvotes: 2

Views: 327

Answers (3)

JwameeQohwiye
JwameeQohwiye

Reputation: 603

I think you've really got two questions, so I'll try to answer them separately.

The first question is "How can I parse a file that looks like this...

DIRT: 3;
STONE: 6;

into names and integers?" You could remove all the whitespace and semicolons from each line, and then split on colon. A cleaner way, in my opinion, would be to use a regular expression:

// 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);
}

If you're not familiar with regular expressions, I encourage you to check them out; they make it very easy to format strings and pull out values. http://regexone.com/

The second question, "how do I store the value alongside the name?", I'm not sure I fully understand. If what you want to do is back each item with the numerical value specified in the file, the dub stylee's advice is good for you. You'll need to place the name as the display member and value as the value member. However, since your data is not in a table, you'll have to put the data somewhere accessible so that the Properties you want to use can be named. I recommend a dictionary:

        // 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";

In this version, I have used Linq to construct the dictionary. If you don't like the Linq syntax, you can use a loop instead:

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));
}

Upvotes: 1

jbriggs
jbriggs

Reputation: 353

You could also use FileHelpers library. First define your data record.

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

Then you read in your data like so:

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

Upvotes: 0

Patrick
Patrick

Reputation: 736

Try doing something like this:

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

remember it will require to use using System.Linq; if your want ot reference the selected value of the combobox you can use cmb.SelectedValue; cmb.SelectedText;

Upvotes: 2

Related Questions