关于winforms:从datagridview中删除多行后索引超出范围? C#

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

我使用 ArrayList 进行二分搜索。 datagridview 的行被添加到 ArryList。当我从 datagridview 中删除一行时,它几乎可以完美运行。问题是当我从顶部或底部和中间的 datagridview 中删除许多行时,它给了我一个错误。从 ArrayList (datagridview) 中删除一行后,如何刷新或更新 ArrayList

错误:

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

我将行复制到 ArrayList 的代码:

我将此代码放入按钮 MouseEnter 事件中,因此在单击按钮进行搜索之前,它将所有内容复制到 ArrayList.

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

我对所选行的删除代码:

1
2
3
4
5
foreach (DataGridViewRow item in this.dataGridView2.SelectedRows)
{
    dataGridView2.Rows.RemoveAt(item.Index);
    return;
}

我在winform中的二进制搜索代码:

1
2
3
4
5
6
7
8
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");
}

错误发生在:

1
dataGridView2.Rows[index].Selected = true;

打开 csv 后,二分搜索工作正常!

></p>
<p>测试删除功能。</p>
<p><img src=

enter


我已经提出了一个快速的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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());
        }
    }
}

但我建议避免使用 ArrayList,因为它不是强类型。请改用 List<T>。我猜想使用 ArrayList 的原因是 BinarySearch 方法。


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

如果您在arraylist 和datagridview 中有10 个项目,那么从datagridview 中删除2 个,您现在在arraylist 中有10 个项目,在datagridview 中有8 个项目。如果您收到 arraylist(8 或 9)中最后 2 项中的任何一项的索引并尝试访问 datagridview 中这些索引中的项,它将引发异常。

尝试使用数据绑定,然后只对 ArrayList 进行操作。

1
dataGridView2.DataSource = ArrayList;

此外,如果您正在循环删除列表中的项目,请向后执行。从最后一项开始,然后回到开头:

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

执行 foreach 会导致枚举器抛出异常,因为列表已从一个传递更改为下一个传递。


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)?

解决方案:

当我打开两次 csv 文件时,二进制搜索运行良好,但第三次却没有,因为我必须用 ArrayList.Clear(); 清除我的 ArrayList,而不仅仅是 datagridview。然后我可以将 datagridview 行复制到空的 ArrayList.

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

然后->

我将行复制到 ArrayList 的代码:

我将此代码放入按钮 MouseEnter 事件中,因此在单击按钮进行搜索之前,它将所有内容复制到 ArrayList.

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

我对所选行的删除代码:

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

我在winform中的二进制搜索代码:

1
2
3
4
5
6
7
8
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");
}

感谢您阅读它!