Use ASP.NET 2.0's TreeView to Display Hierarchical Data
Next, write a method called FillCustomers in the code behind. This method will be called when the user expands the root node (Customers). The method looks like this:
private void FillCustomers(TreeNode parent) { DataSet ds = GetDataSet("select customerid,companyname from customers order by companyname"); foreach(DataRow row in ds.Tables[0].Rows) { TreeNode node=new TreeNode(); node.Text=row["companyname"].ToString(); node.Value=row["customerid"].ToString(); node.PopulateOnDemand = true; node.SelectAction = TreeNodeSelectAction.SelectExpand; parent.ChildNodes.Add(node); } }
The FillCustomers method makes use of a helper function called GetDataSet that accepts the SQL query and returns a DataSet filled with the results of the supplied query. The following code shows the GetDataSet function:
private DataSet GetDataSet(string sql) { string connstr = @"data source=.\sqlexpress; initial catalog = northwind;integrated security=true"; SqlDataAdapter da = new SqlDataAdapter(sql, connstr); DataSet ds = new DataSet(); da.Fill(ds); return ds; }
TreeNodeSelectAction Value | Description |
---|---|
Expand | Raises either TreeNodeExpanded or TreeNodeCollapsed event, depending on the current expand or collapse state of the node |
Select | Raises SelectedNodeChanged event when a node is selected |
SelectExpand | Raises SelectedNodeChanged and TreeNodeExpanded events when a node is selected |
None | Does not raise any event |
The FillCustomers method accepts a parameter of type TreeNode. This node is nothing but the parent node on which the user has clicked. It is supplied from the TreeNodePopulate event handler. Once you finish configuring the new node, add it to the ChildNodes collection of the parent node.
Along similar lines, create a method called FillOrders(). You will use this method to populate OrderIDs for the selected customer. It looks like this:
private void FillOrders(TreeNode parent) { DataSet ds = GetDataSet("select customerid,orderid from orders where customerid='" + parent.Value + "'"); foreach (DataRow row in ds.Tables[0].Rows) { TreeNode node = new TreeNode(); node.Text = row["orderid"].ToString(); node.Value = row["orderid"].ToString(); node.PopulateOnDemand = false; node.SelectAction = TreeNodeSelectAction.SelectExpand; parent.ChildNodes.Add(node); } }
Note that, because there is no further on-demand population, you set the PopulateOnDemand property to false.
Finally, add the TreeNodePopulate event handler as follows:
protected void TreeView1_TreeNodePopulate (object sender, TreeNodeEventArgs e) { switch (e.Node.Depth) { case 0: FillCustomers(e.Node); break; case 1: FillOrders(e.Node); break; } }
The TreeNodePopulate event handler receives an event argument of type TreeNodeEventArgs. The TreeNodeEventArgs instance provides access to the node that is being expanded via its Node property. Depending on the nesting level, you need to call either the FillCustomers method (if it is a root node) or the FillOrders method (if it is a specific customer node). You do this checking by using the Depth property of the TreeNode class. According to the depth, you call corresponding methods.
Figure 5 shows a sample run of the Web form.
Figure 5: Adding TreeNodes Via Code
Note how all the customer nodes indicate that they are expandable (+), even though they do not contain any child nodes initially. This behavior is because of the PopulateOnDemand property you learned about earlier.
Data Binding with XML File
Just like TreeView, XML documents also represent data in a hierarchical fashion. Expecting a link between TreeView and XML data is quite natural. In fact, with the help of the XmlDataSource control, you can actually data bind your TreeView with an XML document. The final example illustrates how you can do this.Add one more Web form to the Web site. Drag and drop a TreeView, XmlDataSource, and Label on the Web form.
Right-click on your Web site in Solution Explorer and select "Add New Item...". A dialog like the one in Figure 6 will display.
Click here for a larger image.
Figure 6: Add New Items Dialog
Select XML File and name it Books.xml. Add the following markup to the Books.xml file:
<?xml version="1.0" encoding="utf-8" ?> <books> <category name="Web Development"> <subcategory name="ASP.NET" url="~/example2.aspx?id=1"> </subcategory> <subcategory name="Web Services" url="~/example2.aspx?id=2"> </subcategory> <subcategory name="JSP" url="~/example2.aspx?id=3"> </subcategory> </category> <category name="Windows Development"> <subcategory name="Windows Forms" url="~/example2.aspx?id=4"> </subcategory> <subcategory name="ActiveX" url="~/example2.aspx?id=5"> </subcategory> <subcategory name="Smart Client" url="~/example2.aspx?id=6"> </subcategory> </category> <category name="Component Development"> <subcategory name="COM" url="~/example2.aspx?id=7"> </subcategory> <subcategory name="DCOM" url="~/example2.aspx?id=8"> </subcategory> <subcategory name="Remoting" url="~/example2.aspx?id=9"> </subcategory> </category> </books>
The root node is <books> and it contains <category> nodes. The <category> nodes further contain <subcategory> nodes. The <category> tag has an attribute, called name, that represents the name of the book category. Similarly, the <subcategory> tag has an attribute, called name, that represents sub-category name. Additionally, it has an attribute, called url, that points to the Web page where the user is supposed to be navigated. Note that the name attribute corresponds to the Text property and the url attribute corresponds to the NavigateUrl property that you used previously.
Now, open the smart tag of the XmlDataSource control and choose "Configure Data Source...". This will open the dialog in Figure 7.
Click here for a larger image.
Figure 7: Configure Data Source Dialog
Set the DataFile property by entering the name of your XML file. Thus, books.xml will provide data to the XmlDataSource control, which in turn will be supplied to the TreeView.
Page 2 of 3