【问题标题】:Index was out of range after deleting multiple rows from the datagridview? C#从 datagridview 中删除多行后,索引超出范围? C#
【发布时间】:2019-02-06 10:18:22
【问题描述】:

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

错误:

'索引超出范围。必须是非负数且小于集合的大小。 参数名称:index'


我将行复制到 ArrayList 的代码:

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

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

我对所选行的删除代码:

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

我在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");
}

错误发生在:

dataGridView2.Rows[index].Selected = true;

打开 csv 后,二分查找运行良好!

测试删除功能。

从 datagridview 中删除了更多行。

从datagridview中删除很多行后,如果我尝试搜索名称,就会出现错误。


我希望我不会错过我的描述中的任何信息。感谢您阅读它!

【问题讨论】:

  • 错误出现在哪一行?
  • “删除”代码在哪里?
  • 请注意,要使用 BinarySearch,列表应该已经排序
  • @rory.ap 我更新了我的问题
  • 您的删除代码只删除了SelectedRows...中的第一个...这是故意的吗?

标签: c# winforms arraylist datagridview binary-search


【解决方案1】:

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

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

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

dataGridView2.DataSource = ArrayList;

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

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

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

【讨论】:

  • 我没有你所有的代码,所以我无法重现你的代码。我不知道您的 ArrayList 包含哪些类型的项目。另外,你说它对你不起作用,什么不起作用?
  • SelectedItems 存在语法错误,因为未指定。我该怎么做?
  • 对不起,应该是 SelectedRows 而不是 SelectedItems。我已经更新了我的答案。
  • 现在,当我使用您的代码删除一行时,它会出错。:`'索引超出范围。必须是非负数且小于集合的大小。参数名称:index' `
  • 您可以执行while 循环而不是for 并删除第一个循环:while(dataGridView2.SelectedRows.Count == 0){ dataGridView2.Rows.RemoveAt(dataGridView2.SelectedRows[0].Index);}。它更容易且不易出错
【解决方案2】:

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

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&lt;T&gt;。我猜想使用 ArrayList 的原因是BinarySearch 方法。

【讨论】:

  • 不幸的是,我不能投票给你,但这确实有效!所以如果我是对的,我可以将DataSource 添加到我导入的 csv,如果它打开了?
  • 我不知道该怎么做。
  • 您获得该异常的主要原因是 ListOfPeople 与网格行不同步。首先删除表单 ListOfPeople 然后网格
  • 啊我现在很困惑。 :D
  • 为什么不能用我删除项目的方式? btnDelete_Click 方法
【解决方案3】:

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

解决方案:

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

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

然后 ->

我将行复制到 ArrayList 的代码:

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

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

我对所选行的删除代码:

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

我在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");
}

感谢您阅读它!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 2021-11-25
    • 1970-01-01
    • 2016-04-13
    相关资源
    最近更新 更多