You have a couple of issues here. First part of your problem is because you are also removing the datagrid rows using this for-loop
for (int i = 0; i < DataGrid1.Rows.Count; i++)
Say you had a grid with 3 rows in it
Row 1 : "1"
Row 2 : "2"
Row 3 : "3"
If you start at the top and delete row 1 you now get
Row 1 : "2"
Row 2 : "3"
So instead of looking at the "2" value your variable i is now pointing to the "3" value. Follow this through and you "fall off" the end of the grid, usually with an error.
Start your loop at the other end and work backwards
for (int i = DataGrid1.Rows.Count -1; i >= 0; i--)
Next - why do you have
I suspect this was an attempt to get over the problem I described above. You don't want to be changing your loop counter in that way.
Next, why use
inside the loop? This potentially also changes the position of data in your grid. Wait until you have deleted all the rows you want to get rid of and then rebind as a single step.
DataGridViewRow row = new DataGridViewRow();
You don't actually use that new row so why go to the expense of creating it?
I think your code should look more like this (warning, untested)
private void button2_Click(object sender, EventArgs e)
for (int i = DataGrid1.Rows.Count - 1; i >=; i--)
DataGridViewRow row = DataGrid1.Rows[i];
string Name = row.Cells.Value.ToString();
string id = Convert.ToString(row.Cells.Value);
SqlCommand cmd = new SqlCommand("DELETE FROM med WHERE Name =@Name", connect);
int Result = cmd.ExecuteNonQuery();
label6.Text = "Deleted Successfully.";
catch (Exception ex)
I'm not going to pick up on the fact the connection seems to be defined outside this function entirely - in this instance I would probably open the connection outside the loop and close it in a finally statement or use a
statement. I would also give the button a meaningful name rather than the default "button2". All things for you to consider.