0

I use an ArrayList for my binary search. The datagridview's rows is added to the ArryList. When I deleting a single row from the datagridview, it works almost perfectly. The problem is when I delete many rows from the datagridview from the top or the bottom and middle, it gives me an error. How can I refresh or update the ArrayList after I deleted a row from the ArrayList (datagridview)?

The error:

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


My code for copying rows to the ArrayList:

I put this code into the button MouseEnter event, so before I click on button to search it copies everything to the ArrayList.

foreach (var row in dataGridView2.Rows.Cast<DataGridViewRow>())
{
   ArrayList[row.Index] = row.Cells[0].Value.ToString().Trim();
}

My delete code for the selected row(s):

foreach (DataGridViewRow item in this.dataGridView2.SelectedRows)
{
    dataGridView2.Rows.RemoveAt(item.Index);
    return;
}

My code for the binary search in winform:

int index = this.ArrayList.BinarySearch(textBoxBinarySearch.Text);
if (index > -1)
{
    dataGridView2.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
    dataGridView2.Rows[index].Selected = true;
    dataGridView2.CurrentCell = dataGridView2.Rows[index].Cells[0];
    MessageBox.Show("Index is equal to: " + index, "Binary Search");
}

The error is occuring at:

dataGridView2.Rows[index].Selected = true;

After opening a csv, the binary search is working perfectly!

Testing delete function.

enter image description here

Removed more rows from the datagridview.

enter image description here

After removed many rows from the datagridview, if I try to search for the name, the errors is appears.

enter image description here


I hope I don't miss any information from my description. Thanks if you read it trough!

Galarist
  • 27
  • 1
  • 7

3 Answers3

1

The issue appears to be that you're only removing items from the DataGridView but not from the ArrayList then using the arraylist search index against the DataGridView. So if you remove the last item from the DataGridView it still exists in the ArrayList so if you match on that item and attempt to use the index in the DataGridView you will get the index out of range exception.

If you have 10 items in the arraylist and the datagridview then delete 2 from the datagridview you now have 10 items in the arraylist and 8 in the datagridview. If you receive the index of the either of the last 2 items in the arraylist (8 or 9) and attempt to access items in those indicies in the datagridview it will throw the exception.

Try using data binding instead then operate only on the ArrayList.

dataGridView2.DataSource = ArrayList;

Also, if you're looping over a list removing items do it backwards. Start at the item with the last item and work back to the start:

for(int i = dataGridView2.SelectedRows.Count - 1 ; i >= 0 ; i--)
{
    dataGridView2.Rows.RemoveAt(dataGridView2.SelectedRows[i].Index);
}

Doing a foreach causes the enumerator to throw an exception as the list has changed from one pass to the next.

Handbag Crab
  • 1,488
  • 2
  • 8
  • 12
  • I don't have all your code so I can't reproduce what you have. I have no idea what types of items your ArrayList contains. Also, you say it's not working for you, what isn't working? – Handbag Crab Aug 31 '18 at 12:44
  • It has a syntax error for `SelectedItems`, because it is not specified. How can I do that? – Galarist Aug 31 '18 at 13:05
  • Sorry, should be SelectedRows not SelectedItems. I've updated my answer. – Handbag Crab Aug 31 '18 at 13:25
  • Now it gives an error when I deleting a row with your code.: ` 'Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index' ` – Galarist Aug 31 '18 at 13:57
  • Try putting `dataGridView2.SelectedRows.Count - 1` in the for line. – Handbag Crab Aug 31 '18 at 14:05
  • Removing rows is working with your code now. How can I update the `ArrayList`? Still giving that error when I want to search with binary search. After deleting many rows. – Galarist Aug 31 '18 at 14:09
  • 1
    You can do a `while` loop instead of a `for` and remove the first one: `while(dataGridView2.SelectedRows.Count == 0){ dataGridView2.Rows.RemoveAt(dataGridView2.SelectedRows[0].Index);}`. It is easier and not error prone – γηράσκω δ' αεί πολλά διδασκόμε Aug 31 '18 at 14:13
  • @Galarist *....How can I update the ArrayList?*. Is it so difficult to think it your self? Just clear it and refill it as in your question *My code for copying rows to the ArrayList:* – γηράσκω δ' αεί πολλά διδασκόμε Aug 31 '18 at 14:21
  • @Galarist It **did** actually. It found your error and fixed it! Remember your title *Index was out of range after deleting multiple rows from the datagridview? C#*. You asked about why the index was out of range! Now you need other things. Ask a new question. Yours is being answered! – γηράσκω δ' αεί πολλά διδασκόμε Aug 31 '18 at 14:24
  • @γηράσκωδ'αείπολλάδιδασκόμε if I clear the `ArrayList` and then refill with my with that code. It gives that error again. My binary search still not working correctly. – Galarist Aug 31 '18 at 14:35
  • @Galarist Show a **minimal working** example that **reproduces** the problem so we can test it ourselves. – γηράσκω δ' αεί πολλά διδασκόμε Aug 31 '18 at 14:39
  • @galarist Your ArrayList and dataGridView2 are not in sync. If you remove items from dataGridView2 you also need to remove them from ArrayList. If you sort ArrayList you need to sort dataGridView2 as well. As I said in my response, you need to look at data binding your ArrayList to dataGridView2 then when you remove items from ArrayList they'll also be removed from dataGridView2. – Handbag Crab Aug 31 '18 at 15:02
  • I fixed my problem, will post an answer later. – Galarist Aug 31 '18 at 18:04
1

I've put a quick way of doing this:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        PopulateGrid();
    }

    private ArrayList myList = new ArrayList();
    private List<Student> students = new List<Student>();

    private void PopulateGrid()
    {
        students = new List<Student>
        {
            new Student {Lastname = "aa"},
            new Student {Lastname = "bb"},
            new Student {Lastname = "cc"},
            new Student {Lastname = "cc"},
            new Student {Lastname = "cc"},
            new Student {Lastname = "ee"},
            new Student {Lastname = "ff"},
            new Student {Lastname = "ff"},
            new Student {Lastname = "gg"},
            new Student {Lastname = "gg"},
        };

        dataGridView2.DataSource = students;
        myList = new ArrayList(students.Select(x => x.Lastname).ToList());
    }

    public class Student
    {
        public string Lastname { get; set; }
    }

    private void btnSearch_Click(object sender, EventArgs e)
    {
        var index = myList.BinarySearch(textBoxBinarySearch.Text);
        if(index > -1)
        {
            dataGridView2.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
            dataGridView2.Rows[index].Selected = true;
            dataGridView2.CurrentCell = dataGridView2.Rows[index].Cells[0];
            MessageBox.Show("Index is equal to: " + index, "Binary Search");
        }
    }

    private void btnDelete_Click(object sender, EventArgs e)
    {
        if (dataGridView2.SelectedRows.Count > 0)
        {

            var selected = dataGridView2.SelectedRows[0];
            students.RemoveAt(selected.Index);

            dataGridView2.DataSource = null;
            dataGridView2.DataSource = students;
            myList = new ArrayList(students.Select(x => x.Lastname).ToList());
        }
    }
}

But I would advise avoid using ArrayList since it's not strong type. Use List<T> instead. I guess the reason to use ArrayList is BinarySearch method.

Daniel B
  • 3,109
  • 2
  • 33
  • 42
0

I use an ArrayList for my binary search. The datagridview's rows is added to the ArryList. When I deleting a single row from the datagridview, it works almost perfectly. The problem is when I delete many rows from the datagridview from the top or the bottom and middle, it gives me an error. How can I refresh or update the ArrayList after I deleted a row from the ArrayList (datagridview)?

Solution:

When I oppened two times the csv file, the binary search is worked well, but for the third time, it doesn't, because I had to clear my ArrayList with ArrayList.Clear(); not just the datagridview. Then I could copy the datagridview rows to the empty ArrayList.

dataGridView2.Rows.Clear();
ArryList.Clear();

Then ->

My code for copying rows to the ArrayList:

I put this code into the button MouseEnter event, so before I click on button to search it copies everything to the ArrayList.

foreach (var row in dataGridView2.Rows.Cast<DataGridViewRow>())
{
   ArrayList[row.Index] = row.Cells[0].Value.ToString().Trim();
}

My delete code for the selected row(s):

for (int i = dataGridView2.SelectedRows.Count - 1; i >= 0; i--)
{ 
      dataGridView2.Rows.RemoveAt(dataGridView2.SelectedRows[i].Index);
      ListOfPeople.RemoveAt(i);
}

My code for the binary search in winform:

int index = this.ArrayList.BinarySearch(textBoxBinarySearch.Text);
if (index > -1)
{
    dataGridView2.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
    dataGridView2.Rows[index].Selected = true;
    dataGridView2.CurrentCell = dataGridView2.Rows[index].Cells[0];
    MessageBox.Show("Index is equal to: " + index, "Binary Search");
}

Thanks if you read it trough!

Galarist
  • 27
  • 1
  • 7