Удалить несколько строк в DataGridViews - PullRequest
0 голосов
/ 25 апреля 2019

У меня есть родительский класс, определенный следующим образом:

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; }
        }
    }
}

Обратите внимание, что Child_Name имеет следующий формат: Parent_Name + "-" + целое число.

Затем вВ той же форме я создаю два DataGridView (dt1 и dt2).На dt1 каждая строка показывает Parent_Name, а на dt2 каждая строка показывает Child_Name.У каждого родителя может быть несколько дочерних элементов (список).

Теперь я хочу: - удалить родительский элемент (строку) на dt1, также будут удалены все связанные дочерние элементы в dt2 (но не дочерние элементы другого родителя).).

Пока что я сделал:

// 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);
    }
}

Он удалял выбранного родителя, как и ожидалось, но удалял только первого потомка этого родителя (но не остальных).Где я сделал не так?

Большое спасибо!

1 Ответ

0 голосов
/ 25 апреля 2019

Не следует пытаться удалить элементы из той же коллекции, по которой вы выполняете итерацию.
Если вы удалите элемент из коллекции, итератор foreach окажется в невозможной ситуации.Он больше не сможет правильно найти следующую строку в итерации.Это похоже на распиливание ветки, на которой вы сидите

Старый трюк, который нужно использовать здесь, заключается в навигации по коллекции строк с обычной формой for..loop , начиная с последнего элемента вколлекция .Поэтому при удалении элементов счетчик (x) уменьшается, и вы не пропускаете ни одной строки в цикле.

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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...