Рекурсивный поиск управления с LINQ

Если бы я хотел найти проверенные флажки на странице ASP.NET, то я мог бы использовать следующий запрос LINQ.

var checkBoxes = this.Controls
                     .OfType()
                     .TakeWhile(cb => cb.Checked);

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

Вопрос задали здесь:

Нахождение средств управления, которые используют определенный интерфейс в ASP.NET

И полученные ответы non-LINQ, у меня уже есть своя собственная версия рекурсивного поиска управления на типе и идентификаторе как дополнительные методы, но я просто задался вопросом, как легкий это должно сделать в LINQ?

35
задан Community 23 May 2017 в 12:19
поделиться

2 ответа

Возьмите тип/ИДЕНТИФИКАТОР, выезжающий из рекурсии, поэтому просто имейте, "дают мне все средства управления, рекурсивно" метод, например,

public static IEnumerable<Control> GetAllControls(this Control parent)
{
    foreach (Control control in parent.Controls)
    {
        yield return control;
        foreach(Control descendant in control.GetAllControls())
        {
            yield return descendant;
        }
    }
}

Это несколько неэффективно (с точки зрения создания большого количества итераторов), но я сомневаюсь, что Вы будете иметь очень глубокое дерево.

можно тогда записать исходный запрос как:

var checkBoxes = this.GetAllControls()
                     .OfType<CheckBox>()
                     .TakeWhile<CheckBox>(cb => cb.Checked);

(РЕДАКТИРОВАНИЕ: Измененный AllControls к GetAllControls и использованию это правильно как метод.)

45
ответ дан Jon Skeet 27 November 2019 в 07:18
поделиться

Мое предложение для создания AllControls рекурсивный:

    public static IEnumerable<Control> AllControls(this Control parent)
    {
        foreach (Control control in parent.Controls)
        {
             yield return control;
        }
        foreach (Control control in parent.Controls)
        {
            foreach (Control cc in AllControls(control)) yield return cc;
        }
    }

второе foreach странные взгляды, но это - единственный способ, которым я знаю для "сглаживания" рекурсивного вызова.

0
ответ дан Peter Mortensen 27 November 2019 в 07:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: