简体   繁体   English

从datagridview删除多行后索引超出范围? C#

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

I use an ArrayList for my binary search. 我使用ArrayList进行二进制搜索。 The datagridview's rows is added to the ArryList. datagridview的行将添加到ArryList。 When I deleting a single row from the datagridview, it works almost perfectly. 当我从datagridview删除一行时,它几乎可以正常工作。 The problem is when I delete many rows from the datagridview from the top or the bottom and middle, it gives me an error. 问题是,当我从顶部或底部和中间的datagridview中删除许多行时,它给我一个错误。 How can I refresh or update the ArrayList after I deleted a row from the ArrayList (datagridview)? ArrayList (datagridview)删除一行后,如何刷新或更新ArrayList

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: 我的将行复制到ArrayList的代码:

I put this code into the button MouseEnter event, so before I click on button to search it copies everything to the ArrayList . 我将此代码放入按钮MouseEnter事件中,因此在单击按钮进行搜索之前,将所有内容复制到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: 我在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! 打开csv后,二进制搜索运行正常!

Testing delete function. 测试删除功能。

在此处输入图片说明

Removed more rows from the datagridview. 从datagridview中删除了更多行。

在此处输入图片说明

After removed many rows from the datagridview, if I try to search for the name, the errors is appears. 从datagridview中删除许多行后,如果我尝试搜索名称,则会出现错误。

在此处输入图片说明


I hope I don't miss any information from my description. 希望我不要错过任何描述信息。 Thanks if you read it trough! 谢谢,如果你读它的低谷!

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. 问题似乎是您只从DataGridView中删除项目,而不是从ArrayList中删除项目,然后对DataGridView使用arraylist搜索索引。 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. 因此,如果您从DataGridView中删除最后一项,则它仍存在于ArrayList中,因此,如果在该项目上匹配并尝试在DataGridView中使用索引,您将获得索引超出范围的异常。

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. 如果arraylist和datagridview中有10个项目,然后从datagridview中删除2个,则arraylist中现在有10个项目,datagridview中有8个项目。 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. 如果您收到了arraylist中最后两个项目(8或9)中任何一个的索引,并尝试在datagridview中访问这些索引中的项目,它将抛出异常。

Try using data binding instead then operate only on the ArrayList. 尝试使用数据绑定,而不是仅对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. 进行一次foreach会导致枚举数抛出异常,因为列表已从一次传递更改为另一次传递。

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. 但我建议避免使用ArrayList因为它不是强类型。 Use List<T> instead. 请改用List<T> I guess the reason to use ArrayList is BinarySearch method. 我想使用ArrayList的原因是BinarySearch方法。

I use an ArrayList for my binary search. 我使用ArrayList进行二进制搜索。 The datagridview's rows is added to the ArryList. datagridview的行将添加到ArryList。 When I deleting a single row from the datagridview, it works almost perfectly. 当我从datagridview删除一行时,它几乎可以正常工作。 The problem is when I delete many rows from the datagridview from the top or the bottom and middle, it gives me an error. 问题是,当我从顶部或底部和中间的datagridview中删除许多行时,它给我一个错误。 How can I refresh or update the ArrayList after I deleted a row from the ArrayList (datagridview)? ArrayList (datagridview)删除一行后,如何刷新或更新ArrayList

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(); 当我选择两次csv文件时,二进制搜索运行良好,但是第三次​​却没有,因为我必须使用ArrayList.Clear();清除ArrayList ArrayList.Clear(); not just the datagridview. 不只是datagridview。 Then I could copy the datagridview rows to the empty ArrayList . 然后,我可以将datagridview行复制到空ArrayList

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

Then -> 然后->

My code for copying rows to the ArrayList: 我的将行复制到ArrayList的代码:

I put this code into the button MouseEnter event, so before I click on button to search it copies everything to the ArrayList . 我将此代码放入按钮MouseEnter事件中,因此在单击按钮进行搜索之前,将所有内容复制到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: 我在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! 谢谢,如果你读它的低谷!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM