Visual Studio 2008 offers some out-of-the-box features that we can easily create a Treeview control in the form designer without writing much code. However if we need to (Most of time I believe we do) programmatically populate a Treeview menu, particularly if we want to populate a Treeview based on a database table, this does require some codes. In this demo, I am demonstrating how we can populate a Treeview control with database tables. The backend database is Oracle 10g R2, I use the employee table under HR schema. It shouldn’t matter which database you are using, as long as your table or view in hierarchy structure, for instance like:
ID EMP_NAME PARENT_ID
100 Steven
101 Neena 100
102 Lex 100
103 Alexander 102
104 Bruce 103
105 David 103
106 Valli 103
107 Diana 103
108 Nancy 101
- Firstly in the form designer, we drag a Treeview control and make it dock left.
- Drag a Splitter control to the right hand side of the form and make it dock left as shown below.
- Drag a Panel control to the right hand side and make it dock top.
- Drag a Splitter control to the bottom right and make it dock top.
- Drag a third Panel to the bottom right and make it fill the rest of the screen as shown below.
- To populate the TreeViewNode, I am using a recursive function. The tag property is used to store the level of the hierarchy.
using System;
using System.Data;
using System.Windows.Forms;
using System.Data.OracleClient;
namespace TreeViewDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
DataSet dsTreeView = new DataSet();
// Populate public DataSet
private DataSet PopulateDataTable()
{
string connectionString = "Data Source=orcl;Persist Security Info=True; "
+ "User ID=hr;Password=hr;Unicode=True";
string queryString = "select * from employees";
OracleConnection connection = new OracleConnection(connectionString);
OracleCommand command = new OracleCommand(queryString, connection);
OracleDataAdapter da = new OracleDataAdapter(command);
try
{
connection.Open();
if (!dsTreeView.Tables.Contains("emp"))
dsTreeView.Tables.Add("emp");
da.Fill(dsTreeView, "emp");
}
catch (OracleException oex)
{
throw new Exception(oex.Message);
}
finally
{
connection.Close();
}
return dsTreeView;
}
// The level of tree
int intLevel = 0;
// Recursive function to populate Treeview node
public void FillChildren(TreeNode _Parent, int _ParentID)
{
intLevel++;
DataView Data = new DataView(dsTreeView.Tables["emp"]);
Data.RowFilter = "manager_id = " + _ParentID;
// Define the image index in the lowest level
if (Data.Count == 0)
{
_Parent.ImageIndex = 2;
_Parent.SelectedImageIndex = 2;
}
foreach (System.Data.DataRowView foo in Data)
{
TreeNode t = BuildNode((string)foo["last_name"]);
t.Tag = intLevel;
FillChildren(t, int.Parse(foo["employee_id"].ToString()));
_Parent.Nodes.Add(t);
System.Diagnostics.Trace.WriteLine("Added node at level " + intLevel.ToString());
}
intLevel--;
}
private TreeNode BuildNode(string Text)
{
return new TreeNode(Text);
}
private void LoadMenuTreeView()
{
PopulateDataTable();
DataView Data = new DataView(dsTreeView.Tables["emp"]);
Data.RowFilter = "manager_id is null ";
foreach (System.Data.DataRowView foo in Data)
{
TreeNode t = BuildNode((string)foo["last_name"]);
t.Tag = 0;
FillChildren(t, int.Parse(foo["employee_id"].ToString()));
this.treeView1.Nodes.Add(t);
}
this.treeView1.ImageList = this.imageList1;
}
private void Form1_Load(object sender, EventArgs e)
{
LoadMenuTreeView();
}
private void treeView1_AfterExpand(object sender, TreeViewEventArgs e)
{
e.Node.ImageIndex = 1;
}
private void treeView1_AfterCollapse(object sender, TreeViewEventArgs e)
{
e.Node.ImageIndex = 0;
}
}
}
Run the application, we will see a data bound treeview as shown below.
You can easily add some nice features, such as passing a parameter from a treeview to a DataGridView in the right screen or using a status bar at the bottom to display a tree node full path. Hopefully you find it useful. Happy coding.