Larry
Larry

Reputation: 652

TreeView duplicating root nodes, despite there being a single root in Nodes array

I'm currently using TreeView to display a file tree for visualising diffs for a source control project. I have a "Diff" method that recursively edits an existing node in the root "Nodes" array in the TreeView, and then updates the tree afterward.

However, I've encountered an issue where the root node will duplicate for seemingly no reason, despite the debugger telling me there's a single element in the "Nodes" array at the very root of the TreeView, with no indication of an error.

I've already attempted to use "Nodes.Clear()" and then re-add the offending node, however even when clearing the array, the duplicate persists, (even when Nodes.Count is 0). I've also tried using BeginUpdate() and EndUpdate(), but to no avail.

Here's an MCVE:

public partial class BrokenControl : TreeView
{
   public BrokenControl()
   {
       InitializeComponent();
   }

   public void Go(object sender, EventArgs e)
   {
       Nodes.Add("Root");
       Nodes[0] = RecursiveEdit(Nodes[0]);
       Update();
   }

   //This function simply recursively edits the Nodes array.
   int iterations = 10;
   private TreeNode RecursiveEdit(TreeNode node)
   {
      node.Nodes.Add(iterations.ToString());
      iterations--;
      if (iterations<=0)
      {
          return node;
      }

      RecursiveEdit(node.Nodes[0]);
      return node;
   }
}

As mentioned, I only expect there to be a single node on the TreeView when it's updated, but instead I get a duplicate node containing duplicated contents of the first.

Upvotes: 0

Views: 146

Answers (2)

user24878093
user24878093

Reputation: 3

Debugging a TreeView I found that when calling make_unique to create a new child node, that child node begins life as a clone copy of its parent. make_unique does this by calling the (class* const&) variant of the nodes copy constructor. It does NOT call your nodes default constructor (inside which I typically initialise the new object). So in my case the parent is the root node, and the child starts off with the contents of that root node without default initialisation. So to fix this, after calling make_unique, ALWAYS call a method on your new object to default initialise it.

Upvotes: 0

Larry
Larry

Reputation: 652

I managed to fix the issue by using a workaround: instead of directly manipulating the Root node, saving a copy and editing, then clearing and readding, solved my issue.

Still do not know what was causing the dupe even when Nodes.Count was 0 and 1, however this seems to work.

Corrected MCVE:

public partial class BrokenControl : TreeView
{
   ...

   public void Go(object sender, EventArgs e)
   {
       Nodes.Add("Root");
       TreeNode savedNode = RecursiveEdit(Nodes[0]);

       //This fixes it.
       Nodes.Clear();
       Nodes.Add(savedNode);

       Update();
   }

   ...
}

Upvotes: 1

Related Questions