0

我在左侧创建了一个目录和文件浏览器 TreeView。我希望用户能够浏览树并检查他们想要移动到另一个树视图的文件和目录。

另一个 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;
    }

任何人都可以帮助使用此代码,以便它递归地添加检查节点(及其父节点,无论检查状态如何)。我需要维护目录层次结构。

谢谢你的帮助!

4

2 回答 2

1

一个相当(不太干净和不喜欢)的解决方案可能是首先克隆树,然后删除未检查的分支。

否则,当你添加一个节点时,编写一个递归方法来遍历节点的父节点,直到你找到根节点。并且通过检查 childNode.parent 是否已经存在来简单地优化它,只需忽略分支并继续前进。即回溯到根节点。

于 2013-03-19T13:51:24.580 回答
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);
        }

    }
于 2013-03-20T10:40:12.310 回答