문제

TreeView의 모든 노드를 쉽게 반복하고. 점검 된 속성을 검사 한 다음 확인 된 모든 노드를 삭제할 수있는 방법은 무엇입니까?

간단 해 보이지만 반복하는 컬렉션을 수정해서는 안됩니다. "Foreach"루프의 가능성을 제거합니다. (.nodes.remove 호출은 컬렉션을 수정합니다.) 이것이 시도되면, 그 효과는 .Checked 노드의 약 절반 만 제거됩니다.

하나가 두 번의 패스를 사용하는 경우에도 먼저 임시 색인 목록을 작성한 다음 두 번째 패스에서 인덱스별로 제거됩니다. 인덱스 목록의 무결성을 무효화하는 인덱스가 변경됩니다.

그렇다면이 작업을 수행하는 가장 효율적인 방법은 무엇입니까?

다음은 좋아 보이지만 실제로는 .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);
                    }
                }
            }

(그렇습니다.

도움이 되었습니까?

해결책

이렇게하면 노드가 열거 된 후 노드를 제거하고 노드의 N- 계층에 재귀 적으로 사용할 수 있습니다.

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

다른 팁

노드를 거꾸로 걸어보십시오. 이렇게하면 인덱스가 노드 크기를 지나서 증가하지 않습니다.

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

효율적으로 수행하려면 점검 된 노드가 점검 될 때 추적해야합니다. 확인 된 트리 노드를 목록에 저장하고 확인되지 않은 상태에서 제거하십시오.

고유 한 키와 많은 노드가있는 경우 사전도 고려할 수도 있습니다. 그러나 당신이 10-50 만 다루고 있다면 아마 큰 차이를 만들지 않을 것입니다.

그런 다음 전체 트리를 통해 반복하는 대신 (작은) 노드 목록을 통해 루프를 반복합니다.

반복하는 동안 선택되지 않은 새 항목 목록을 구성한 다음 TreeView를 해당 새 목록으로 다시 바꾸어 놓을 수 있습니다 (이전 목록을 폐기).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top