Похоже, проблема заключается в том, что вы удаляете только элементы из DataGridView, но не из ArrayList, а затем используете индекс поиска arraylist для DataGridView. Таким образом, если вы удалите последний элемент из DataGridView, он все еще существует в ArrayList, поэтому, если вы сопоставите этот элемент и попытаетесь использовать индекс в DataGridView, вы получите индекс вне диапазона исключений.
Если у вас есть 10 элементов в списке массивов и в представлении сетки данных, то удалите 2 из вида сетки данных, теперь у вас есть 10 элементов в списке массивов и 8 в виде сетки данных. Если вы получите индекс одного из последних 2 элементов в массиве списков (8 или 9) и попытаетесь получить доступ к элементам в этих признаках в представлении данных, это вызовет исключение.
Попробуйте вместо этого использовать привязку данных, а затем работать только с ArrayList.
dataGridView2.DataSource = ArrayList;
Кроме того, если вы перебираете список, удаляя элементы, делайте это задом наперед. Начните с элемента с последним элементом и вернитесь к началу:
for(int i = dataGridView2.SelectedRows.Count - 1 ; i >= 0 ; i--)
{
dataGridView2.Rows.RemoveAt(dataGridView2.SelectedRows[i].Index);
}
Выполнение foreach заставляет перечислитель генерировать исключение, поскольку список меняется с одного прохода на следующий.