views:

47

answers:

3

Following code, credit: Guffa.


Hello All,

I'm trying to add controls to a Form at runtime based on the information found in a Plain Text File. The structure? of the text file is always the same, and will not change. Example:

File.txt:

Label
"This is a label"
320, 240


Explanation:

Control
Text
Location


The following code, provided to me by Guffa, doesn't cause any errors or anything, but at the same time, nothing happens at all. And I'm not sure why... Can somebody please explain why the label doesn't get created and added to the form with the right info attached to it?

MatchCollection lines = Regex.Matches(File.ReadAllText(fileName), @"(.+?)\r\n""([^""]+)""\r\n(\d+), (\d+)\r\n");
foreach (Match match in lines) {
   string control = match.Groups[1].Value;
   string text = match.Groups[2].Value;
   int x = Int32.Parse(match.Groups[3].Value);
   int y = Int32.Parse(match.Groups[4].Value);
   Console.WriteLine("{0}, \"{1}\", {2}, {3}", control, text, x, y);

   if(control == "Label")
   {
      Label label = new Label();
      label.Text = text;
      canvas.Controls.Add(label); // canvas is a Panel Control.
      label.Location = new Point(x, y);
   }

}

I hope that I have clearly explained my situation. Any help at all would be greatly appreciated.

Thanks for taking the time to read. jase

+3  A: 

My guess is that your file doesn't have quite the right format. If you step into the code, does it match anything?

If so, what gets printed to the console?

Have you tried it with the exact sample shown in the question? While I haven't tried it in a form, I've tried the rest of the code above with the sample file, and it works fine.

Personally I don't think I'd use a regex to match all of the lines like this - it makes it harder to diagnose issues - but it should work okay if the file is correct. You say you don't understand the regex provided - that's another good reason not to use it, to be honest. Even if it's entirely correct, it's not a good idea to use code that you don't understand - you won't be able to maintain it.

I would personally just read the lines three at a time and then deal with them that way. Something like this:

private static readonly Regex LocationPattern = new Regex(@"^(\d+), (\d+)$");
...

using (TextReader reader = File.OpenText(filename))
{
    while (true)
    {
        string control = reader.ReadLine();
        string text = reader.ReadLine();
        string location = reader.ReadLine();

        if (control == null)
        {
            break;
        }
        if (text == null || location == null)
        {
            // Or however you want to handle this...
            throw new InvalidConfigurationFileException
                ("Incorrect number of lines");
        }
        if (text.Length < 2 || !text.StartsWith("\"") || !text.EndsWith("\""))
        {
            // Or however you want to handle this...
            throw new InvalidConfigurationFileException
                ("Text is not in quotes");
        }
        text = text.Substring(1, text.Length - 2);
        Match locationMatch = LocationPattern.Match(location);
        if (!locationMatch.Success)
        {
            // Or however you want to handle this...
            throw new InvalidConfigurationFileException
                ("Invalid location: " + location);
        }
        // You could use int.TryParse if you want to handle this differently
        Point parsedLocation = new Point(int.Parse(match.Groups[1].Value),
                                         int.Parse(match.Groups[2].Value));

        // Now the rest of the code before
    }
}

As you can tell, it's a lot more code - but each part of it is relatively simple. Regular expressions are powerful if you're happy to handle them, but unless something is complicated to express "longhand" I often find it easier to maintain the longer way. Just a personal preference though.

Jon Skeet
Thank you Jon, although I have already accepted an answer - I would really appreciate your sample code for your approach. I think I might also look into buying a book on Regex...Soon (frightened)
baeltazor
+2  A: 

Blind guess: I see the last \r\n in the regex is not optional. Possible that your input file is missing a return character after the last line?

Additional note about sucking at regular expressions: there are some tools that will help you experiment with regular expressions, which might be useful, for example, to understand what's going on in this particular case. I always use Expresso, which among other things analyzes the structure of the regular expression you provide and explains what it does.

Paolo Tedesco
thank you very much orsogufo! you've made my day!!!!!!!!!!!! :D
baeltazor
I'm glad I helped :) but be aware about Jon Skeet's suggestion that a single regular expression is not the best way to parse your file...
Paolo Tedesco
A: 

Another possibility is that you forgot to add canvas (Panel control) to another control so the chain of controls inside canvas is not displayed and you would maybe not see that the canvas itself doesn't display. Which guess is the best? :-)

jdehaan