Add all array elements to datagridview rows except one

I read the text file line by line and paste it into an array.

Then I have this custIndex list, which contains specific indexes, the indexes of the items array, which I am testing to check if they are valid codes. (for example, custIndex [0] = 7, so I check the value in elements [7-1] to find out if this is really in the two dictionaries that I'm here). Then, if there is invalid code, I add a row (items array) to dataGridView1.

The fact is that some of the columns in dataGridView1 are Combo Box columns, so the user can select the correct value. When I try to add an array of elements, I get an exception: "The following exception occurred in the DataGridView: System.ArgumentException: DataGridViewComboBoxCell value is not valid."

I know that the combo box was correctly added with the correct data source, because if I just add several elements to the array of elements in dataGridView1, for example, as soon as the elements are [0], the combo box displays fine and there are no exceptions thrown. I think the problem is that I'm trying to add the wrong value to the items array in the dataGridView1 row.

I'm not sure how to deal with this. Is there a way to add all elements to elements except this value? Or can I add a value from the elements and show it in the combo box along with filled out drop-down elements?

if(choosenFile.Contains("Cust")) { var lines = File.ReadAllLines(path+"\\"+ choosenFile); foreach (string line in lines) { errorCounter = 0; string[] items = line.Split('\t').ToArray(); for (int i = 0; i <custIndex.Count; i++) { int index = custIndex[i]; /*Get the state and country codes from the files using the correct indices*/ Globals.Code = items[index - 1].ToUpper(); if (!CountryList.ContainsKey(Globals.Code) && !StateList.ContainsKey(Globals.Code)) { errorCounter++; dataGridView1.Rows.Add(items); } }//inner for if (errorCounter == 0) dataGridView2.Rows.Add(items); }//inner for each }//if file is a customer file 
+6
source share
1 answer

Say your text file contains:

Australia PNG, India Africa
Bali Indonesia Indonesia
France England Scotland Ireland Greenland
Germany Bahama Hawaii
Greece Colombia Mexico Mexico Peru Argentina - New Zealand Russia USA

And let's say that your DataGridView is set to 3 columns, and the second is a combo box.

enter image description here

When you fill the grid and fill the combobox column incorrectly, you will get an error.

The way to solve it is to "handle / declare explicitly" the DataError event and, more importantly, populate the list column correctly.

 private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e) { //Cancelling doesn't make a difference, specifying the event avoids the prompt e.Cancel = true; } private void dataGridView2_DataError(object sender, DataGridViewDataErrorEventArgs e) { e.Cancel = true; } 

So, imagine that the 2nd column contains a drop-down list of countries, and the 1st and 3rd columns contain text fields.

For the 1st and 3rd columns, these are just rows, so I create a class to represent each row:

 public class CountryData { public string FirstCountry { get; set; } public string ThirdCountry { get; set; } } 

For the 2nd column with the "Countries" list, I created a separate class, because I will bind it to the data source of the 2nd column.

 public class MultiCountryData { public string[] SeceondCountryOption { get; set; } } 

Filling the grid with combobox columns and the like, as shown here: fooobar.com/questions/230604 / ... is not good practice. You want to separate your business logic from your presentation for a more encapsulated, polymorphic and abstract approach that will facilitate unit testing and maintenance. Hence DataBinding.

Here is the code:

 namespace BusLogic { public class ProcessFiles { internal List<CountryData> CountryDataList = new List<CountryData>(); internal List<MultiCountryData> MultiCountryDataList = new List<MultiCountryData>(); internal void foo(string path,string choosenFile) { var custIndex = new List<int>(); //if (choosenFile.Contains("Cust")) //{ var lines = File.ReadAllLines(path + "\\" + choosenFile); foreach (string line in lines) { int errorCounter = 0; string[] items = line.Split('\t'); //Put all your logic back here... if (errorCounter == 0) { var countryData = new CountryData() { FirstCountry = items[0], ThirdCountry = items[2] }; countryDataList.Add(countryData); multiCountryDataList.Add( new MultiCountryData() { SeceondCountryOption = items[1].Split(',')}); } //} } } } 

In your presentation project, the button code is:

  imports BusLogic; private void button1_Click(object sender, EventArgs e) { var pf = new ProcessFiles(); pf.foo(@"C:\temp","countries.txt"); dataGridView2.AutoGenerateColumns = false; dataGridView2.DataSource = pf.CountryDataList; multiCountryDataBindingSource.DataSource = pf.MultiCountryDataList; } 

I set dataGridView2.AutoGenerateColumns = false; because during development I added 3 columns; 1st text column, 2nd column with a list and columns of 3rd text.

The trick of linking the second column to the list is BindingSource . During development> right-click on DataGridView> select "Edit Columns"> select the second column> select "DataSource"> "Add DataSource Project> select" Object "> then mark the multiCountry class and click" Finish ".

enter image description here

enter image description here

Also set the 1st column of DataPropertyName for FirstCountry and the 3rd column of DataPropertyName for ThirdCountry, so when you bind the data, the mapping is done automatically.

enter image description here

Finally, remember to set the BindingSource DataMember property for a member of the SeceondCountryOption class of multiCountry.

enter image description here

Here is the code demo http://temp-share.com/show/HKdPSzU1A

+6
source

All Articles