Question

Si je voulais trouver des cases à cocher sur une page ASP.NET, je pourrais utiliser la requête LINQ suivante.

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

Cela fonctionne bien si les cases à cocher sont imbriquées dans la collection de contrôles actuelle, mais j'aimerais savoir comment étendre la recherche en explorant les collections de contrôles des contrôles de niveau supérieur.

La question a été posée ici:

Recherche de contrôles utilisant une certaine interface dans ASP.NET

Et ayant reçu des réponses autres que LINQ, j'ai déjà ma propre version d'une recherche de contrôle récursive sur le type et l'ID en tant que méthodes d'extension, mais je me demandais si c'était facile à faire dans LINQ?

Était-ce utile?

La solution

Prenez le type / ID en vérifiant la récursivité, il vous suffit donc de placer un " donnez-moi tous les contrôles de manière récursive " méthode, par exemple

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

C'est quelque peu inefficace (en termes de création de nombreux itérateurs), mais je doute que vous ayez un arbre très profond .

Vous pouvez ensuite écrire votre requête d'origine en tant que:

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

(EDIT: a modifié AllControls en GetAllControls et l’utilise correctement comme méthode.)

Autres conseils

public static IEnumerable<Control> AllControls(this Control container)
{
    //Get all controls
    var controls = container.Controls.Cast<Control>();

    //Get all children
    var children = controls.Select(c => c.AllControls());

    //combine controls and children
    var firstGen = controls.Concat(children.SelectMany(b => b));

    return firstGen;
}

Maintenant, sur la base de la fonction ci-dessus, nous pouvons faire quelque chose comme ceci:

public static Control FindControl(this Control container, string Id)
{
    var child = container.AllControls().FirstOrDefault(c => c.ID == Id);
    return child;
}

Ma suggestion pour rendre le AllControls récursif est la suivante:

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

Le deuxième foreach a l’air bizarre, mais c’est le seul moyen que je connaisse pour "aplatir". l'appel récursif.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top