Question

Comment parcourir facilement tous les nœuds d'un TreeView, examiner leur propriété .Checked puis supprimer tous les nœuds cochés?

Cela semble simple, mais vous n'êtes pas censé modifier une collection à travers laquelle vous effectuez une itération, ce qui élimine la possibilité d'un "foreach". boucle. (L'appel .Nodes.Remove est en train de modifier la collection.) Si cela est tenté, cela signifie que seulement environ la moitié des noeuds .Checked sont supprimés.

Même si l’on utilisait deux passes: d’abord créer une liste d’index temporaires, puis de supprimer par index lors de la seconde passe - les index changeraient à chaque suppression, annulant l’intégrité de la liste d’index.

Alors, quel est le moyen le plus efficace de le faire?

Voici un exemple de code qui a l'air bien, mais ne supprime en réalité qu'environ la moitié des nœuds .Checked.:

            foreach (TreeNode parent in treeView.Nodes)
            {
                if (parent.Checked)
                {
                    treeView.Nodes.Remove(parent);
                }
                else
                {
                    foreach (TreeNode child in parent.Nodes)
                    {
                        if (child.Checked) parent.Nodes.Remove(child);
                    }
                }
            }

(Oui, l'intention est uniquement d'élaguer les nœuds d'un arbre de deux niveaux.)

Était-ce utile?

La solution

Ceci supprimera les nœuds après les avoir énumérés et peut être utilisé de manière récursive pour les n-tiers de nœuds.

void RemoveCheckedNodes(TreeNodeCollection nodes)
{
    List<TreeNode> checkedNodes = new List<TreeNode>();

    foreach (TreeNode node in nodes)
    {
        if (node.Checked)
        {
            checkedNodes.Add(node);
        }
        else
        {
            RemoveCheckedNodes(nodes.ChildNodes);
        }
    }

    foreach (TreeNode checkedNode in checkedNodes)
    {
        nodes.Remove(checkedNode);
    }
}

Autres conseils

Essayez de parcourir les nœuds en arrière. Ainsi, votre index n'augmentera pas au-delà de la taille de votre nœud:

for( int ndx = nodes.Count; ndx > 0; ndx--)
{
  TreeNode node = nodes[ndx-1];
  if (node.Checked)
  {
     nodes.Remove(node);
  }
   // Recurse through the child nodes...
}

Si vous voulez le faire efficacement, vous devez garder une trace des nœuds vérifiés au fur et à mesure de leur vérification. Stockez les noeuds d'arbre cochés dans une liste (et supprimez-les lorsqu'ils ne sont pas cochés).

Si vous avez une clé unique et BEAUCOUP de nœuds à surveiller, vous pourriez également envisager un dictionnaire. Mais si vous avez seulement affaire à 10-50, cela ne fera probablement pas une grande différence.

Ensuite, au lieu de parcourir l’ensemble de l’arborescence, vous ne faites que parcourir votre (plus petite) liste de nœuds.

En effectuant une itération, vous pouvez créer une nouvelle liste d’éléments non vérifiés, puis réassocier votre arborescence à cette nouvelle liste (en supprimant l’ancien).

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