Index was out of range after deleting multiple rows from the datagridview? C#

自古美人都是妖i 提交于 2021-02-08 10:13:08

问题


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.

Removed more rows from the datagridview.

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


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


回答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.




回答2:


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.




回答3:


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!



来源:https://stackoverflow.com/questions/52114489/index-was-out-of-range-after-deleting-multiple-rows-from-the-datagridview-c-sha

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!