5

I'm working with windows forms and I want to copy entire tree view with their childrens in order set in clipboard in KeyDown event

First I try to set parent nodes as:

  private void tvProjectList_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == (Keys.C))
            {
                var treeViewParents = "";
                foreach (TreeNode tn in tvProjectList.Nodes)
                {
                    treeViewParents += tn.Text + Environment.NewLine;
                }
                Clipboard.SetText(treeViewParents);

            }
        }

But it just get one node instead all nodes. How am I supposed to do it? Regards

Update:

In order to get Nodes and their childrens I have

   private void tvProjectList_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == (Keys.C))
            {

                foreach (TreeNode node in tvProjectList.Nodes)
                {
                    PrintNodesRecursive(node);
                }
            }
        }



 public void PrintNodesRecursive(TreeNode oParentNode)
        {
            Console.WriteLine(oParentNode.Text);

            var treeViewParents = "";
            StringBuilder sb = new StringBuilder();

            // Start recursion on all subnodes.
            foreach (TreeNode oSubNode in oParentNode.Nodes)
            {
                sb.Append(oSubNode.Text + Environment.NewLine);
                 PrintNodesRecursive(oSubNode);
            }
            Clipboard.SetText(sb.ToString());

        }

But string builder always come with empty string... Why data is not saved in string builder? Regards

Jonathan
  • 601
  • 9
  • 26
  • Try writing a [recursive method retrieving all the treenodes](https://stackoverflow.com/questions/4702051/get-a-list-of-all-tree-nodes-in-all-levels-in-treeview-controls). Then you could itterate those nodes and concat them using a `StringBuilder`. – Fixation Nov 20 '18 at 19:10
  • You are creating a new `StringBuilder` inside the `PrintNodesRecursive` recursive method, this will create one for every node inside your treeview and copy the text of just that level to the clipboard in the end. When your method finishes, only the last TreeNode's first level will be on your clipboard. Instead you should create one before calling the recursive method and use that one in each itteration. – Fixation Nov 20 '18 at 19:36

1 Answers1

4

Expanding on my comment, here's an example implementation of a recursive method to accomplish this:

private void CopyTreeViewToClipboard(TreeView treeView)
{
    // Make a StringBuilder to store the text of each individual node
    var treeViewStringBuilder = new StringBuilder();

    // Initiate the recursive method
    GetTreeViewNodesText(treeView.Nodes, treeViewStringBuilder);

    // because StringBuilder is a reference type we do not need use a return value 
    //   and we can copy to clipboard using the already existing reference
    Clipboard.SetText(treeViewStringBuilder.ToString());
}

private void GetTreeViewNodesText(TreeNodeCollection nodesInCurrentLevel, StringBuilder sb, int level = 0)
{
    foreach (TreeNode currentNode in nodesInCurrentLevel)
    {
        // Add some padding (spaces) in front to display the current level
        sb.Append(new string(' ', level * 2));
        // Add the text and terminate the line \n\r
        sb.AppendLine(currentNode.Text);

        // Recursion happens here, it's level + 1 instead of level++ because we
        //   do not want to alter the level for the next nodes in nodesInCurrentLevel
        GetTreeViewNodesText(currentNode.Nodes, sb, level + 1);
    }
}
Fixation
  • 969
  • 6
  • 12