简体   繁体   中英

Delete multiples rows in DataGridViews

I have a parent class defined as following:

using System.Collections.Generic;

namespace Test
{
    public class GeneralClass
    {
        public class Parent
        {
            public string Parent_Name { get; set; }
            public List<Child> List_Child { get; set; } = new List<Child>();
        }

        public class Child
        {
            public string Child_Name { get; set; }
        }
    }
}

Please note that the Child_Name has the following format: Parent_Name + "-" + an integer number.

Then in the same Form, I create two DataGridView (dt1 and dt2). On the dt1, each row shows the Parent_Name and on the dt2 each row shows the Child_Name. Each parent can have multiple children (List).

Now I want to: - Delete a parent (a row) on dt1, it would also delete all the associated children in dt2 (but not the children of other parent).

So far, what I've done is

// Iteration over selected parents
foreach (DataGridViewRow row_dt1 in dt1.SelectedRows)
{
    if (!row.IsNewRow)
    {
        // Find parent name of actual row
        string parent_name = row_dt1.Cells[0].Value.ToString();
        // Iteration over all rows of children
        foreach (DataGridViewRow row_dt2 in dt2.Rows)
        {
            // Find child name
            object val1 = row_dt2.Cells[0].Value;
            // If child name starts with parent name, remove this child from the DataGridView (dt2)
            if (val1 != null && val1.ToString().StartsWith(parent_name + "-"))
            {
                dt2.Rows.Remove(row_dt2);
            }
        }
        // Now remove the parent from dt1
        dt1.Rows.Remove(row_dt1);
    }
}

It deleted the selected parent as expected but it only deleted the first child of this parent (but not the others). Where did I do wrong?

Thank you very much!

You shouldn't try to remove items from the same collection you are iterating over.
If you remove an item from the collection the foreach iterator will be put in an impossible situation. It will be no more able to correctly find the next row in the iteration. It is like sawing the branch you are sitting on

The old trick to use here is to navigate the rows collection with a normal for..loop starting from the last item in the collection . So while you remove items, the counter (x) decrease and you don't skip any rows in your loop.

foreach (DataGridViewRow row_dt1 in dt1.SelectedRows)
{
    if (!row.IsNewRow)
    {
        // Find parent name of actual row
        string parent_name = row_dt1.Cells[0].Value.ToString();
        // Iteration over all rows of children
        for(int x = dt2.Rows.Count - 1; x >= 0; x--)
        {
            // Find child name
            DataGridViewRow row_dt2 = dt2.Rows[x];
            object val1 = row_dt2.Cells[0].Value;
            // If child name starts with parent name, remove this child from the DataGridView (dt2)
            if (val1 != null && val1.ToString().StartsWith(parent_name + "-"))
            {
                dt2.Rows.Remove(row_dt2);
            }
        }
        // Now remove the parent from dt1
        dt1.Rows.Remove(row_dt1);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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