35 votes

Recherche de contrôle récursive avec Linq

Si je voulais trouver coché les cases à cocher sur une ASP.NET la page que je pouvais utiliser la suite de Linq.

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

Cela fonctionne bien si les cases sont imbriqués dans le contrôle en cours de collecte, mais je voudrais savoir comment étendre la recherche par le forage vers le bas dans le contrôle des collections de haut-niveau des contrôles.

La question a été posée ici:

Trouver contrôles qui utilisent une certaine interface dans ASP.NET

Et reçu non-Linq réponses, j'ai déjà ma propre version d'un circuit de contrôle de la recherche sur le type et l'ID que les méthodes d'extension, mais juste demandé comment facile c'est de le faire dans Linq?

45voto

Jon Skeet Points 692016

Prenez le type / ID en vérifiant la récursion, il vous suffit donc de choisir une méthode "donnez-moi tous les contrôles, récursivement", 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 un 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 initiale 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.)

2voto

Arthur Dzhelali Points 21
   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 basé sur la fonction ci-dessus, nous pouvons faire quelque chose comme ça.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X