title: Windows Forms TreeView - Bind hierarchical recursive datasource
body: <p>I'm converting a WPF client in Windows Forms and I got some problems trying to replicate the TreeView control structure.</p>
  
  <p>In the first project I have a custom factory that builds a structure starting from an input string that is basically a XML.
  The return type is a collection.
  Custom TreeNode:</p>
  
  <pre><code>public class TreeViewNode
  {
      public TreeViewNode() { }
      public DocumentKey DocKey { get; set; }
      public string Text { get; set; }
      public IList&lt;TreeViewNode&gt; Children { get; set; }
  }
  </code></pre>
  
  <p>Factory:</p>
  
  <pre><code>public class TreeViewFactory
  {
      public IList&lt;TreeViewNode&gt; GetSctructure(DocumentKey docKey, string structure, bool loadAllParents)
      {
          XDocument xmlDocstructure = CommonXmlValueParser.GetXDocument(structure);
  
          var parentsNodes = (from item in xmlDocstructure.Descendants("structure_item")
                              where (CommonXmlValueParser.GetAttribute(item, "level") == "1")
                              select new TreeViewNode
                              {
                                  Text = GetNodeText(item),
                                  DocKey = new DocumentKey()
                                  {
                                      Bank = docKey.Bank,
                                      Ud = int.Parse(CommonXmlValueParser.GetElement(item.Element("ud"))),
                                      Master = int.Parse(CommonXmlValueParser.GetElement(item.Element("master"))),
                                      NVig = int.Parse(CommonXmlValueParser.GetElement(item.Element("nvig"))),
                                      Subjects = docKey.Subjects
                                  },
                                  Children = GetChildrenNodes(item, 2, docKey.Bank)
                              }).ToList();
  
          return parentsNodes;
      }
  
  
      private IList&lt;TreeViewNode&gt; GetChildrenNodes(XElement element, int level, int dataBank)
      {
          var childrenNodes = (from item in element.Descendants("structure_item")
                               where (CommonXmlValueParser.GetAttribute(item, "level") == level.ToString())
                               select new TreeViewNode
                               {
                                   Text = GetNodeText(item),
                                   DocKey = new DocumentKey()
                                   {
                                       Bank = dataBank,
                                       Ud = int.Parse(CommonXmlValueParser.GetElement(item.Element("ud"))),
                                       Master = int.Parse(CommonXmlValueParser.GetElement(item.Element("master"))),
                                       NVig = int.Parse(CommonXmlValueParser.GetElement(item.Element("nvig"))),
                                   },
                                   Children = GetChildrenNodes(item, level + 1, dataBank)
                               }).ToList();
  
          return childrenNodes;
      }
  }
  </code></pre>
  
  <p>Binding:</p>
  
  <pre><code>void CreateTree(object tree, EventArgs e)
  {
      //...
      TreeViewFactory treeFactory = new TreeViewFactory();
      var documentStructure = treeFactory.Structure(document.DocumentKey, document.XmlStructure, true);
      this.tabMainControl.document.SetTreeViewStructureNodes(documentStructure);
  }
  
  public void SetTreeViewStructureNodes(IList&lt;TreeViewNode&gt; nodes)
  { 
      this.treeView.ItemsSource = nodes;
  }
  </code></pre>
  
  <p><strong>Update:</strong></p>
  
  <p>I made the TreeViewNode derive from TreeNode and changed the method SetTreeViewStructureNodes in:</p>
  
  <pre><code>private TreeView SetTreeViewStructureNodes(IList&lt;TreeViewNode&gt; nodes)
  {
      TreeView treeView = new TreeView();
      treeView.Nodes.AddRange(nodes.ToArray());
  
      return treeView;
  }
  </code></pre>
  
  <p>still that doesn't achieve my goal as it's still not rendered...</p>
  
  <p>In Windows Forms as far as I know it's not possible to associate a sort of datasource that is a whatever type collection (implements IEnumerable).
  Apart from using 3rd party components, how can I solve my problem. My experience on WinForms is pretty short and just when I learnt to manage much better WPF they decided to shift it :(</p>
  
  <p>Appreciate all your help, regards.</p>
  
  <p><strong>Update2</strong>:
  Piece of WinForms User Control where treeView is filled:</p>
  
  <pre><code>TreeView treeView = (TreeView)documentViewControl.Controls["treeViewStructure"];
  
  
  TreeViewFactory treeFactory = new TreeViewFactory();
  var documentStructure = treeFactory.GetStructure(document.DocumentKey, document.XmlStructure, true);
  treeView = this.SetTreeViewStructureNodes(documentStructure);
  </code></pre>
  
  <p>Basically I'm moving from an UC to another. Both of them are part of 2 Tabs, children of a TabControl.</p>