2009-05-05 6 views
7

TreeView의 모든 노드를 쉽게 반복 처리하고 .Checked 속성을 검사 한 다음 확인 된 노드를 모두 삭제할 수 있습니까?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); 
        } 
       } 
      } 

(예, 의도는 두 가지입니다 트리에서 노드를 치기 만입니다 레벨이 깊어집니다.

답변

6

이 그들을 열거 한 후 노드를 제거하고 노드의 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); 
    } 
} 
1

반복되는 동안 검사되지 않은 항목의 새 목록을 만든 다음 트리 뷰를 새 목록으로 다시 바인딩 할 수 있습니다 (이전 항목은 삭제).

7

노드를 거꾸로 걸어보십시오.

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

가장 효율적인 방법입니다. – Romias

+0

이전 질문이지만 가장 효율적인 방법 인 +1입니다. – TimFoolery

+0

이것을 다시 살펴보면 ... 몇 가지 수정을하면 약간 더 빠를 것입니다. for 루프 표제에서 다음과 같이 변경합니다 :'int ndx = nodes.Count-1'과'ndx> = 0'은 루프를 통과 할 때마다 -1이 발생하지 않도록합니다. 사물의 웅대 한 계획에서, 약간의 여분의 subtractions는 많이 의미하지 않을 것이다. 그러나 헤이. .. 왜 그렇지 않습니까? – TimFoolery

3

효율적으로 수행하려면 체크 표시된 노드를 추적해야합니다. 체크 된 트리 노드를 목록에 저장합니다 (선택 해제 된 노드는 제거합니다).

고유 한 키가 있고 많은 노드를 추적하면 사전도 고려할 수 있습니다. 그러나 만약 당신이 10-50만을 다루고 있다면 큰 차이를 내지 못할 것입니다.

그러면 전체 트리를 반복하면서 노드 목록을 반복합니다.

관련 문제