Domanda

Come si può facilmente scorrere tutti i nodi in un TreeView, esaminare la loro proprietà .Checked e quindi eliminare tutti i nodi controllati?

Sembra semplice, ma non dovresti modificare una raccolta attraverso la quale stai iterando, eliminando la possibilità di un "foreach" ciclo continuo. (La chiamata .Nodes.Remove sta modificando la raccolta.) Se viene tentato, l'effetto è che viene rimossa solo circa la metà dei nodi .Checked.

Anche se si dovessero usare due passaggi: prima creando un elenco di indici temporanei, quindi rimuovendo per indice al secondo passaggio - gli indici cambieranno ad ogni rimozione, invalidando l'integrità dell'elenco degli indici.

Quindi, qual è il modo più efficiente per farlo?

Ecco un esempio di codice che sembra buono, ma in realtà rimuove solo circa la metà dei nodi .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);
                    }
                }
            }

(Sì, l'intenzione è solo di eliminare i nodi da un albero profondo due livelli.)

È stato utile?

Soluzione

Questo rimuoverà i nodi dopo averli enumerati e può essere usato ricorsivamente per i livelli n di nodi.

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

Altri suggerimenti

Prova a camminare indietro tra i nodi. In questo modo il tuo indice non aumenta oltre la dimensione del tuo nodo:

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

Se vuoi farlo in modo efficiente devi tenere traccia dei nodi controllati man mano che vengono controllati. Memorizzare i nodi dell'albero selezionati in un elenco (e rimuoverli quando sono deselezionati).

Se hai una chiave univoca e MOLTI nodi per tenerne traccia potresti prendere in considerazione anche un dizionario. Ma se hai a che fare solo con il 10-50 probabilmente non farà una grande differenza.

Quindi, invece di passare in rassegna l'intero albero, fai semplicemente un giro nella tua (più piccola) lista di nodi.

Durante l'iterazione potresti costruire un nuovo elenco di elementi non selezionati e quindi ricollegare il tuo treeview a quel nuovo elenco (scartando quello vecchio).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top