Can some one help with the code how I am going to populate a treeview. In my database i have a talbe with the following coloums: ID, ParentId, NodeText. Now i have the data in class named Cateogry and in it i have all the above colums. Then I created a list of type category and in it i have all recoreds. Now I want to view them in a tree vew. Can someone help me with the code?

Here is a simplified way of doing it.
Typically, If using a database, I would avoid using the category class all together
but that is not what you were asking for.

Anyway, All this form has is a TreeView component and an untyped dataset. The onLoad takes off and loads a
dataset from code (just to avoid having to create a table, and all that connection stuff).
Then I load the List<Category> with the data.
Finally build the tree using a recursive method named getChildren.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace treeTest
{
    public partial class Form1 : Form
    {
        private List<Category> items = new List<Category>();
        public Form1()
        {
            InitializeComponent();
        }
        /*
         * dataSet1 has a table with 3 columns
         * col#1=ID (int)
         * col#2=ParentID (int)
         * col#3=NodeText (string)
         */ 
        private void Form1_Load(object sender, EventArgs e)
        {
            // Load up a dataset with values - usually from a database, but
            // here I can show the data without using a real database.
            dataSet1.Tables[0].Rows.Add(1, 0, "First Node");
            dataSet1.Tables[0].Rows.Add(3, 1, "Node 3.1");
            dataSet1.Tables[0].Rows.Add(4, 1, "Node 4.1");
            dataSet1.Tables[0].Rows.Add(5, 0, "Node 5.0");
            dataSet1.Tables[0].Rows.Add(6, 5, "Node 6.5");
            dataSet1.Tables[0].Rows.Add(7, 5, "Node 7.5");
            dataSet1.Tables[0].Rows.Add(8, 5, "Node 8.5");
            dataSet1.Tables[0].Rows.Add(9, 5, "Node 9.5");
            dataSet1.Tables[0].Rows.Add(10, 6, "Node 10.6");
            dataSet1.Tables[0].Rows.Add(11, 6, "Node 11.6");
            dataSet1.Tables[0].Rows.Add(12, 11, "Node 12.11");
            dataSet1.Tables[0].Rows.Add(13, 11, "Node 13.11");
            dataSet1.Tables[0].Rows.Add(14, 11, "Node 14.11");
            dataSet1.Tables[0].Rows.Add(15, 11, "Node 15.11");

            // Populate the items array of Catagory from the dataset
            foreach(DataRow dr in dataSet1.Tables[0].Rows)
                items.Add( new Category( (int)dr[0], (int)dr[1], (string)dr[2] ));
            
            // Build the treeview from the catagory list
            buildtree();

        }

        private void buildtree()
        {
            treeView1.Nodes.Clear();    // Clear any existing items
            treeView1.BeginUpdate();    // prevent overhead and flicker
            LoadBaseNodes();            // load all the lowest tree nodes
            treeView1.EndUpdate();      // re-enable the tree
            treeView1.Refresh();        // refresh the treeview display
        }

        private void LoadBaseNodes()
        {
            int baseParent = 0;                 // Find the lowest root category parent value
            TreeNode node;
            foreach (Category cat in items)
            {
                if (cat.ParentID < baseParent)
                    baseParent = cat.ParentID;
            }
            foreach (Category cat in items)         // iterate through the categories
            {
                if (cat.ParentID == baseParent)     // found a matching root item
                {
                    node = treeView1.Nodes.Add(cat.NodeText); // add it to the tree
                    node.Tag = cat;                 // send the category into the tag for future processing
                    getChildren(node);              // load all the children of this node
                }
            }
        }

        // recursive tree loader. Passes back in a node to retireve its childre
        // until there are no more children for this node.
        private void getChildren(TreeNode node)
        {
            TreeNode Node = null;
            Category nodeCat = (Category)node.Tag;  // get the category for this node
            foreach (Category cat in items)         // locate all children of this category
            {
                if (cat.ParentID == nodeCat.ID)     // found a child
                {
                    Node = node.Nodes.Add(cat.NodeText);    // add the child
                    Node.Tag = cat;                         // set its tag to its category
                    getChildren(Node);                      // find this child's children
                }
            }
        }
    }

    class Category 
    {
        public int ID;
        public int ParentID;
        public string NodeText;
        public Category(int ID, int ParentID, string NodeText)
        {
            this.ID = ID;
            this.ParentID = ParentID;
            this.NodeText = NodeText;
        }
        public override string ToString()
        {
            return this.NodeText;
        }
    }
}

If this solves your problem, please mark it as solved, So I get credit for the work,
Thanks,
Jerry

Comments
Great work as always.Am linking to this in another thread!

Hi, I have a similar situation only I don´t want to do it trough a class, how can I make it so the treeview will load up directly from the db?
The fields on my db are basically the same as posted from samudebr
Thanks very much, I will really appreciate any help

I solved it as follows. Hope it helps
Got it somewhere from the web, can't seem to find the source:

TABLE [Category] (
PK	[Row_Id] [int] NOT NULL,
	[Category_Father_Id] [int] NULL,
	[Category_Name] [varchar](50) NULL,
 )
private void PopulateRootLevel()
    {

        SqlConnection objConn = new SqlConnection(ConfigurationManager.ConnectionStrings["connection_name"].ToString());
        SqlCommand objCommand = new SqlCommand("select Row_Id, Category_Name as Name,(select count(*) FROM dbo.Category WHERE Category_Father_Id =sc.Row_Id) childnodecount FROM Category sc where Category_Father_Id = 0", objConn);

        SqlDataAdapter da = new SqlDataAdapter(objCommand);
        DataTable dt = new DataTable();
        da.Fill(dt);

        PopulateNodes(dt, TreeView1.Nodes);
    }

    private void PopulateNodes(DataTable dt, TreeNodeCollection nodes)
    {
        foreach (DataRow dr in dt.Rows)
        {
            TreeNode tn = new TreeNode();
            tn.Text = dr["Name"].ToString();
            tn.Value = dr["Row_Id"].ToString();
            nodes.Add(tn);

            //If node has child nodes, then enable on-demand populating
            tn.PopulateOnDemand = ((int)dr["childnodecount"] > 0);
        }

    }

    private void PopulateSubLevel(int parentid, TreeNode parentNode)
    {
        SqlConnection objConn = new SqlConnection(ConfigurationManager.ConnectionStrings["connection_name"].ToString());
        SqlCommand objCommand = new SqlCommand("select Row_Id,Category_Name as Name,(select count(*) FROM Category WHERE Category_Father_Id=sc.Row_Id) childnodecount FROM Category sc where Category_Father_Id= @parentid", objConn);
        objCommand.Parameters.Add("@parentid", SqlDbType.Int).Value = parentid;

        SqlDataAdapter da = new SqlDataAdapter(objCommand);
        DataTable dt = new DataTable();
        da.Fill(dt);
        PopulateNodes(dt, parentNode.ChildNodes);
    }
    protected void TreeView1_TreeNodePopulate(object sender, TreeNodeEventArgs e)
    {
        PopulateSubLevel(Convert.ToInt32(e.Node.Value), e.Node);
    }

Edited 6 Years Ago by __avd: Added [code] tags. For easy readability, always wrap programming code within posts in [code] (code blocks).

This article has been dead for over six months. Start a new discussion instead.