2013-03-19 4 views
0

왼쪽에 파일 및 디렉토리 브라우저 TreeView를 만들었습니다. 사용자가 트리를 탐색하고 다른 트리 뷰로 이동하려는 파일 및 디렉토리를 확인할 수 있기를 바랍니다.모든 트리 노드를 하나의 트리 뷰에서 다른 트리 뷰로 복사합니다 (체크되지 않은 부모 포함). C#

다른 TreeView는 온라인에서 TreeViewColumn이라는 사용자 정의 컨트롤입니다. 그 컨트롤을 사용하여 사용자가 선택한 파일 및 폴더에 다른 데이터 (범주, 특성)를 추가 할 수 있습니다.

내가 겪고있는 문제는 두 가지입니다. 모든 아이들을 재귀 적으로 추가해야하지만 (체크 아웃 할 수는 있지만) 체크되지 않은 부모를 체크 (상위 계층 유지)해야합니다. 이 재귀 적으로 노드를 확인 (에 관계없이 검사 상태의 부모,)을 추가하도록

private void IterateTreeNodes(TreeNode originalNode, TreeNode rootNode) 
    { 
     //Take the node passed through and loop through all children 
     foreach (TreeNode childNode in originalNode.Nodes) 
     { 
      // Create a new instance of the node, will need to add it to the recursion as a root item 
      // AND if checked it needs to get added to the new TreeView. 
      TreeNode newNode = new TreeNode(childNode.Text); 
      newNode.Tag = childNode.Tag; 
      newNode.Name = childNode.Name; 
      newNode.Checked = childNode.Checked; 
      if (childNode.Checked) 
      { 
       // Now we know this is checked, but what if the parent of this item was NOT checked. 
       //We need to head back up the tree to find the first parent that exists in the tree and add the hierarchy. 
       if (tvSelectedItems.TreeView.Nodes.ContainsKey(rootNode.Name)) // Means the parent exist? 
       { 

        tvSelectedItems.TreeView.SelectedNode = rootNode; 
        tvSelectedItems.TreeView.SelectedNode.Nodes.Add(newNode); 
       } 
       else 
       { 
        AddParents(childNode); 

        // Find the parent(s) and add them to the tree with their CheckState matching the original node's state 
        // When all parents have been added, add the current item. 
       } 
      } 
      IterateTreeNodes(childNode, newNode); 
     } 

    } 

    private TreeNode AddParents(TreeNode node) 
    { 
     if (node.Parent != null) 
     { 
      //tvDirectory.Nodes.Find(node.Name, false); 
     } 
     return null; 
    } 

사람이 코드에 도움이 없습니다. 디렉터리 계층 구조를 유지해야합니다.

도움 주셔서 감사합니다.

답변

0

나는 그것을 작동시켰다. 나는 @Yahya가 말한 것을 이미 알고 있었고, 나는 더 쉬운 방법/더 나은 접근 방법을 기대하고 있었다.

아래의 코드는 분명히 최적은 아니지만 필자는이 점을 개선하기 위해 노력할 것입니다. 그러나이 시점에서 왼쪽의 트리 뷰를보고 CheckedState와 상관없이 모든 체크 항목 (및 그의 부모)을 복사합니다. 오른쪽 트리보기.

희망적으로이 정보는 누군가에게 도움이되고 @Yahya에 답해 주셔서 감사합니다. 개선의 여지가 있지만 일회용 유틸리티라는 점에 유의하십시오.

private void cmdMoveRight_Click(object sender, EventArgs e) 
    { 
     tvSelectedItems.TreeView.Nodes.Clear(); 
     // Traverse first level Tree Nodes 
     foreach (TreeNode originalNode in tvDirectory.Nodes) 
     { 

      TreeNode newNode = new TreeNode(originalNode.Text); 
      newNode.Name = originalNode.Name; 
      newNode.Tag = originalNode.Tag; 
      newNode.Checked = originalNode.Checked; 

      //Only add to the new treeview if the node is checked 
      if (originalNode.Checked) 
      { 
       tvSelectedItems.TreeView.Nodes.Find(originalNode.Parent.Name,true)[0].Nodes.Add(newNode); 
      } 
      //Start recursion - this will be called for each first level node - there should technically only be 1 "ROOT" node. 
      IterateTreeNodes(originalNode, newNode); 
     } 

    } 


    private void IterateTreeNodes(TreeNode originalNode, TreeNode rootNode) 
    { 
     //Take the node passed through and loop through all children 
     foreach (TreeNode childNode in originalNode.Nodes) 
     { 
      // Create a new instance of the node, will need to add it to the recursion as a root item 
      // AND if checked it needs to get added to the new TreeView. 
      TreeNode newNode = new TreeNode(childNode.Text); 
      newNode.Tag = childNode.Tag; 
      newNode.Name = childNode.Name; 
      newNode.Checked = childNode.Checked; 
      if (childNode.Checked) 
      { 
       // Now we know this is checked, but what if the parent of this item was NOT checked. 
       //We need to head back up the tree to find the first parent that exists in the tree and add the hierarchy. 
        TreeNode[] nodestest = tvSelectedItems.TreeView.Nodes.Find(childNode.Parent.Name, true); 
        if (nodestest.Length > 0) 
        { 
         tvSelectedItems.TreeView.Nodes.Find(childNode.Parent.Name,true)[0].Nodes.Add(newNode); 
        } 
        else 
        { 
         AddParents(childNode);// Find the parent(s) and add them to the tree with their CheckState matching the original node's state 


        } 
      } 
      //recurse 
      IterateTreeNodes(childNode, newNode); 
     } 

    } 

    private void AddParents(TreeNode node) 
    { 

     if (node.Parent != null)// Check if parent is null (would mean we're looking at the root item 
     { 
      TreeNode[] nodestest = tvSelectedItems.TreeView.Nodes.Find(node.Parent.Name, true); 
      if (nodestest.Length > 0) 
      { 

       TreeNode[] nodes = tvDirectory.Nodes.Find(node.Name, true); 
       TreeNode newNode = new TreeNode(nodes[0].Text); 
       newNode.Name = nodes[0].Name; 
       newNode.Tag = nodes[0].Tag; 
       newNode.Checked = nodes[0].Checked; 
       tvSelectedItems.TreeView.Nodes[node.Parent.Name].Nodes.Add(newNode); 
      } 
      else 
      { 
       AddParents(node.Parent); 

       TreeNode newNode = new TreeNode(node.Text); 
       newNode.Name = node.Name; 
       newNode.Tag = node.Tag; 
       newNode.Checked = node.Checked; 
       tvSelectedItems.TreeView.Nodes.Find(node.Parent.Name,true)[0].Nodes.Add(newNode); 

      } 
     } 
     else // deal with root node 
     { 
      TreeNode rootNode = new TreeNode(node.Text); 
      rootNode.Name = node.Name; 
      rootNode.Tag = node.Tag; 
      rootNode.Checked = node.Checked; 
      tvSelectedItems.TreeView.Nodes.Add(rootNode); 
     } 

    } 
1

오히려 깨끗하고 좋지 않은 솔루션은 먼저 트리를 복제 한 다음 검사되지 않은 분기를 제거하는 것입니다.

그렇지 않으면 노드를 추가 할 때 루트가 될 때까지 노드의 부모 노드를 통과하는 재귀 적 방법을 작성하십시오. childNode.parent가 이미 존재하는지 확인하여 간단히 최적화하십시오. 분기를 무시하고 계속 진행하십시오. 루트 노드로 역 추적.