-1

I've been stuck on this problem for a little while now. I'm able to read information from a bunch (100) Textboxes and save the data into a CSV file but reading that information back into the form has me a little befuddled, I'm only trying to load the first 11 strings to start with. I can load the CSV into a List but I can't seem to move that data from the list to my Textboxes. Is there something I'm missing with my approach?

        public List<string> LoadCsvFile(string filePath)
    {
        var reader = new StreamReader(File.OpenRead(filePath));
        List<string> searchList = new List<string>();


        while (!reader.EndOfStream)
        {
            var line = reader.ReadLine();
            searchList.Add(line);
            for (int i = 0; i < 11; i++)
            {
                string date = searchList[i];
                string dropdownindex = searchList[i];
                LasttextBox.Text = searchList[i];
                FirsttextBox.Text = searchList[i];
                EmailtextBox.Text = searchList[i];
                PhonetextBox.Text = searchList[i];
                HometextBox.Text = searchList[i];
                InfotextBox.Text = searchList[i];
                PrimarytextBox.Text = searchList[i];
                EmailtextBox.Text = searchList[i];
                SecondaryEmailtextBox.Text = searchList[i];
            }
        }
        return searchList;
    }

The error I'm getting is:

System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index'

I appreciate any help you can provide.

SomethingStrange
  • 121
  • 1
  • 12
  • You read the same part 11 times. And you repeat this until you are and of file. – akop Feb 11 '18 at 20:17
  • 2
    There is a fair amount there that makes no sense. As for the Exception, the awesome debugger at your very fingertips would show you some of the problems. When you read the first line, there are not 11 things in that List. And if it is a CSV it is still one line when you read it, so you are trying to put the same line in each Text control over and over – Ňɏssa Pøngjǣrdenlarp Feb 11 '18 at 20:22
  • 1
    Walk through your code with the debugger. Then you see that you add 1 line and immediately loop through 11 list items. And then you assign the same value to all textboxes. – Hans Kesting Feb 11 '18 at 20:29
  • You will also want to Google the actual error message as basic research: 3600 c# related posts on this site for that exception – Ňɏssa Pøngjǣrdenlarp Feb 11 '18 at 20:41

2 Answers2

1

You are confusing lines with fields, and you don't even really need the List based on what it looks like you are trying to do. It seems like you are trying to assign field values to your text boxes.

Assuming your csv file looks similar to below(You have the e-mail textbox duplicated by the way):

Date,DropDownIndex,LastName,FirstName,Email,Phone,Home,Info,Primary,Email,SecondaryEmail

You can use Linq to parse your CSV file into an anonymous class with all the values you want and then loop through and assign those to your text boxes

For example:

var csvRecords = File
            .ReadAllLines(filePath)
            .Select(c => c.Split(',')).Select(c => new
            {
                Date = c[0],
                DropDown = c[1],
                LastName = c[2],
                FirstName = c[3],
                Email = c[4],
                Phone = c[5],
                Home = c[6],
                Info = c[7],
                Primary = c[8],
                Email2 = c[9],
                SecondaryEmail = c[10]
            }).ToList();

foreach (var csvRecord in csvRecords)
        {
            var date = csvRecord.Date;
            var dropdownindex = csvRecord.DropDown;
            LasttextBox.Text = csvRecord.LastName;
            FirsttextBox.Text = csvRecord.FirstName;
            EmailtextBox.Text = csvRecord.Email;
            PhonetextBox.Text = csvRecord.Phone;
            HometextBox.Text = csvRecord.Home;
            InfotextBox.Text = csvRecord.Info;
            PrimarytextBox.Text = csvRecord.Primary;
            EmailtextBox.Text = csvRecord.Email2;
            SecondaryEmailtextBox.Text = csvRecord.SecondaryEmail;
        }

Some things you will need to consider is if your CSV file only contains comma delimiters and no double quote qualifiers as there could potentially be commas in the actual values which will then throw off the positions of your various fields. If you are still wanting to return a List via the method, you can't return the anonymous typed list, so you will need to create a class, and then instead of using the new in the Linq select, you would use new and assign the fields the same way.

Darthchai
  • 757
  • 8
  • 17
  • This solution worked the best for my scenario. I do have an issue with the CSV since (as you pointed out) I'm not able to navigate to the second row of fields without a comma to end the first row of data. My CSV looks like this: 11-Feb,0,a,b,c,d,e,f,g,h,i 11-Feb,1,j,k,l,m,n,o,p,q,r Any suggestions for reading the second row in the CSV? – SomethingStrange Feb 11 '18 at 22:20
1

This approach is more scalable, i.e., it will work with any number of csv file rows and/or text boxes so long as you have control over the names of the text boxes. This design ignores lines from the csv file that there is no text box for

public Form1()
{
    InitializeComponent();

    //simulate a list loaded from a csv file
    IList<string> stringsFromCsv = new List<string>
    {
        "from csv line dog",
        "from csv line cat",
        "from csv line fish",
        "from csv line frog",
        "from csv line squirrel",
        "from csv line turtle",
        "from csv line squid",
        "from csv line bass",
        "from csv line tiger",
        "from csv line lion"
    };

    //make a collection of all the controls in the groupbox (or form, or whatever)
    Control.ControlCollection controls = groupBox1.Controls;

    int listIndex = 0;

    //loop based on the number of items from the csv file
    while (listIndex <= stringsFromCsv.Count - 1)
    {
        //create a text box name from the current list index
        string expectedTextBoxName = "textBox" + ((listIndex + 1).ToString());

        //this is brute force, but step thru all the controls until
        //you find a text box whose name matches 
        foreach (Control control in controls)
        {
            //skip the control if its not a text box
            if (control.GetType().Name != "TextBox")
                continue;

            if (control.Name == expectedTextBoxName)
            {
                control.Text = stringsFromCsv[listIndex];
                break;
            }

        }

        listIndex = listIndex + 1;

        if (listIndex > stringsFromCsv.Count - 1)
            break;
    }
}

enter image description here