Pergunta

Como se pode facilmente percorrer todos os nós em um TreeView, examinar sua propriedade .checked e exclua todos nós verificado?

Parece simples, mas você não deve modificar uma coleção através do qual você é a iteração, eliminando a possibilidade de um loop "foreach". (A chamada .Nodes.Remove é modificar a recolha.) Se este for tentada, o efeito é que apenas cerca de metade dos nós .checked são removidos.

Mesmo que se utilizar duas passagens: em primeiro lugar a criação de uma lista de índices temporários, e removendo depois por índice na segunda passagem - os índices se alteraria com cada remoção, invaliding a integridade da lista de dice.

Então, o que é a maneira mais eficiente de fazer isso?

Aqui está um exemplo de código que parece ser bom, mas na verdade só remove cerca de metade dos nós .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);
                    }
                }
            }

(Sim, a intenção é apenas para nós poda de uma árvore que é de dois níveis de profundidade.)

Foi útil?

Solução

Isto irá remover os nós depois de enumerar-los, e pode ser usado de forma recursiva para n-tiers de nós.

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

Outras dicas

Tente andar através dos gânglios para trás. Dessa forma, o índice de não aumentar passado o seu tamanho nó:

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 você quiser fazê-lo de forma eficiente você precisa manter o controle dos nós verificados como eles são verificados. Armazenar os nós da árvore verificados em uma lista (e removê-los como eles são desmarcada).

Se você tem uma chave única e um monte de nós para manter o controle de que você pode considerar um dicionário também. Mas se você está lidando apenas com 10-50 provavelmente não vai fazer uma grande diferença.

Então, em vez de loop através de toda a árvore que você acabou de loop thru sua lista (menor) de nós.

Enquanto a iteração você poderia construir uma nova lista de itens sem controle e, em seguida, re-bind sua árvore para que a nova lista (descartando o antigo).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top