Extended TreeView
 
Published: 22 May 2007
Abstract
In this article Mohyuddin examines how to create a custom control that extends the ASP.NET 2.0 TreeView control with the help of a sample application.
by G. Mohyuddin
Feedback
Average Rating: 
Views (Total / Last 10 Days): 44948/ 70

Introduction

It is a TreeView Control that has been extended from the ASP.NET TreeView shipped with .NET Framework 2.0. By extending it from the built in TreeView control, the purpose is to have all basic features of the existing TreeView with some new features, which are highly required but are not supported by the ASP.NET TreeView control. This article does not explain how to extend a TreeView control. That will be covered in a separate article, while this article primarily focuses on how to use this Extended TreeView.

Extended TreeView provides the following important functionalities which are lacking in ASP.NET 2.0 TreeView.

It saves its expansion state.

It is automatically bindable with Multiple sitemaps; also changeable dynamically.

It is bindable with a Database by providing connection string and other necessary information directly.

It is also bindable with dataset programmatically.

Using Extended TreeView

Here is the header of the Extended TreeView. It shows its name and default properties.

Listing 1

namespace ExtendedControls
{
namespace TreeView
{
  [ToolboxData("<{0}:XTreeView runat=server></{0}:XTreeView1>")]
   public class XTreeView : System.Web.UI.WebControls.TreeView
{
...

I will explain here how to use the aforementioned functionalities in Extended TreeView. Let us see them one by one.

Saving the Expansion State

The ASP.NET 2.0 TreeView does not persist in its expansion state. You can either collapse all or expand all the tree nodes. It really becomes troublesome when TreeView has a good number of nodes in multiple hierarchal levels. While navigating from one page to another, the hierarchal expansion state of the TreeView gets lost. Again, we have to expand it to that level and navigate to the desired pages. It becomes of no use when one wishes to have expansion state of TreeView maintained on post backs. Hence, the point comes to have this very crucial feature in TreeView. Extended TreeView supports this by default, you do not need do any thing.

Figure 1

Binding with Multiple Sitemaps

ASP.NET 2.0 TreeView is bindable with one sitemap per website only named with Web.sitemap. The ASP.NET Sitemap Provider only looks for a site map with this name. The only way to use multiple sitemaps is to nest the sitemaps, having the parent with same name, Web.sitemap. No matter even if you will add another TreeView control on page, it again expects the Web.sitemap. It does not work in salutations where we want to customize the look of a tree view according to the category. The Extended TreeView works great for us and overcomes this problem. Now we can use as many sitemaps as we wish in a website (without nesting) and can bind them with their corresponding XTreeViews. 

To work with multiple sitemaps follow these steps.

Add a new sitemap to your web site and name it, say CommonUser.sitemap. Save it in any folder, preferably App_Data for security reasons. This will not allow the client to see it. All contents of this folder are inaccessible to the client.  

Add nodes and set their properties in the sitemap file as shown below.

Listing 2

<?xml version="1.0" encoding="utf-8" ?>
<siteMap>
  <siteMapNode value="~/Home.aspx" title="Home">
  </siteMapNode>
  <siteMapNode  value="~/Default.aspx"  title="User Tasks" >
    <siteMapNode value="~/Profile.aspx" title="View" >
    <siteMapNode value="~/Profile.aspx" title="Profile" />
    <siteMapNode value="~/WeeklyWorkTimeDetail.aspx" title="Work Time Detail" >
        <siteMapNode value="~/WeeklyWorkTimeDetail.aspx" title="Weekly"/>
         <siteMapNode value="~/MonthlyWorkTimeDetail.aspx" title="Monthly"/>
        <siteMapNode value="~/YearlyWorkTimeDetail.aspx" title="Yearly"/>
      </siteMapNode>
    <siteMapNode value="~/WarningComments.aspx" title="Warning and Comments" />
  </siteMapNode>
  </siteMapNode>
 </siteMap>

DO NOT use URL property of node, use Value property instead. By using URL browser, it transfers to the next page without making a server round trip that does not allow saving the expansion sate of the nodes on server. Yet by using VALUE property the page is redirected; a server round trip provides a chance to save the expansion state.

Drag the XTreeView control from the control bar and drop on the page.

Listing 3

<cc1:XTreeView ID="XTreeView1" runat="server">
</cc1:XTreeView>

From the Property pane you will see a new property category Sitemap, it has one property Sitemap. Browse and select it.  That is it. The following image shows this.

Figure 2

For more sitemaps repeat the steps listed above.

View the page in browser you will see that all TreeView are not only successfully bound with their corresponding sitemaps, but also persist their expansion state.

Figure 3

Binding with Database

Generally, binding a TreeView with database requires much to do with code. It requires opening connection, populating a dataset with all required tables and establishing the relationship between them. XTreeView minimizes this effort by providing you few properties to bind it with database directly. Before mentioning these properties, I would like to explain shortly the necessary information ASP.NET TreeView requires for binding with database. 

Generally binding a TreeView with database requires the following steps.                            

Open Connection

Populate Dataset with the parent table.

Populate Dataset with the child table if any.

Establish the relation between these two tables added to the dataset on the basis of the primary and foreign key relationship. (This can be achieved by taking a Relation object, instantiating it with parent child field information and adding it to the Relation collection of the Dataset.)

Repeat the previous two steps for each next child table if any. (The relation will be maintained between the current child and its immediate parent table.)

Now create the nodes of the tree recursively for each row of the Dataset’s parent table with all related rows of the Dataset’s child table under that primary key.

The following figure shows all the properties for XTreeView binding with database.

Figure 4

 

Now let us take a look at these properties that do the same job for us without writing any code. I have put these properties under a new category database in the property pane for the sake of simplicity and better understanding.

ConnectionString property is mandatory and required to be set with a valid connection string as shown below.

Listing 4

<cc1:XTreeView ID="XTreeView1" runat="server"
 ConnectionString="Data Source=gmohyd-serv;Initial Catalog=pakistan_db;Integrated Security=True"
......
</cc1:XtreeView>

Parent node has the following properties.

ParentTableName:  Name of the parent table.  (Mandatory)

ParentNodeTextField: Name of the field of parent table to be displayed as the node text. (Optional, if not set XtreeView takes the second column as node text field.)

ParentNodeValueField: Name of the field of parent table that has to be set as value. Value field can be used for saving page URL's if required, otherwise it is suitable to save ID's. (Optional, if not set, XtreeView takes the first column as node text field.)

ParentChildRelationField:  Name of the field (primary key) of parent table that is being used as foreign key in child table. (Mandatory if there is some child of it.)

The child has the following properties.

ChildTableName:  Name of the Child table.  (Mandatory)

ChildNodeTextField: Name of the field of Child table to be displayed as the node text. (Optional, if not set, XtreeView takes the second column as node text field.)

ChildNodeValueField: Name of the field of Child table that has to be set as value. Value field can be used for saving page URL's if required, otherwise it is suitable to save ID's. (Optional, if not set, XtreeView takes the first column as node text field.)

ChildParentRelationField:  Name of the field (foreign key) of the child table that is being used as primary key in parent table. (Mandatory)

ChildGrandChildRelationField:  Name of the field (primary key) of this immediate parent table that is being used as foreign key in grand child table. (Mandatory, if there is, it is child)

Grand Child has the following properties.

GrandChildTableName:  Name of the Grand Child table.  (Mandatory)

GrandChildNodeTextField: Name of the field of Grand Child table to be displayed as the node text. (Optional, if not set, XtreeView takes the second column as node text field.)

GrandChildNodeValueField: Name of the field of Grand Child table that has to be set as the value. Value field can be used for saving page URL's if required, otherwise it is suitable to save ID's. (Optional, if not set, XtreeView takes the first column as node text field.)

GrandChildChildRelationField:  Name of the field (foreign key) in the grand child table that is being used as primary key in immediate parent table. (Mandatory)

You may have noticed that most of the properties are optiona;l if you do not set them, they are set with default fields.  For binding XTreeView with relational database we need the following information:

Name of table(s)

Name of the relation field(s) with (immediate) parent and (immediate) child, a primary key field in case of parent table and foreign key field in case of child table.

A real world example

Let us take a real world example to use XTreeView. Here, I have the database of Pakistan’s cities. There are three tables in it. They are related with each other with parent child relationship. The following figure shows this.

Figure 5

In Pakistan we have Provinces, a province can have multiple regional Divisions and a division can have multiple Districts. Hence, as shown in the above diagram, we have Provinces as parent table, Divisions as child table that has ProvinceID as foreign key, and Districts as the grand child table having DivisionID as the foreign key. Now let us see how we can bind this database with XtreeView. First, drag XTreeView control and drop on the page and set the aforementioned properties. The following listing shows this.

Listing 5

<cc1:XTreeView ID="XTreeView1"
 runat="server"
 ConnectionString="Data Source=gmohyd-serv;Initial Catalog=pakistan_db;Integrated Security=True"  
ParentTableName="Provinces"
ParentNodeTextField="ProvinceName" 
ParentNodeValueField="ProvinceURL" 
ParentChildRealtionField="ProvinceID" 
ChildTableName="Divisions" 
ChildNodeTextField="DivisionName" 
ChildNodeValueField="DivisionURL" 
ChildParentRelationField="ProvinceID" 
ChildGrandChildRelationField="DivisionID"
GrandChildTableName="Districts"
GrandChildNodeTextField="DistrictName"
GrandChildNodeValueField="DistrictURL"
GrandChildRelationField="DivisionID" >
</cc1:XTreeView>

The properties in bold are mandatory. If you do not set other properties, even then it works fine. By default, it takes the first field as the value field and the second field as the text field. If you have tables with this design then you do not need to set all properties, go for only the mandatory ones.

You might have noticed that in Child part of properties we have two properties for the relation fields. Since it is mandatory to relate the child with its parent and its grand child, we require ChildParentRelationField  and ChildGrandChildRelationField for its relation with parent and grand child,respectively.  

Hence it accomplishes binding XTreeView with database. Here is the output when viewed in the browser.

Figure 6

Binding with Dataset Programmatically

There may be the situations when it would be required to bind the XTreeView programmatically. Sometimes it becomes necessary to have more control on what an extended control does implicitly. XTreeView has property DataSet that is to be set programmatically after populating it with tables and setting its relations. The following code listing shows this.

Listing 6

SqlConnection dbCon = new
 SqlConnection("Data Source=gmohyd-serv;Initial
 Catalog=pakistan_db;Integrated Security=True");
dbCon.Open();
DataSet ds = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Provinces", dbCon);
DataTable parentTable = new DataTable("Provinces ");
adapter.Fill(parentTable);
ds.Tables.Add(parentTable);
adapter = new SqlDataAdapter("SELECT * FROM Divisions", dbCon);
DataTable childTable = new DataTable("Divisions");
adapter.Fill(childTable);
ds.Tables.Add(childTable);
adapter = new SqlDataAdapter("SELECT * FROM Districts", dbCon);
DataTable gchildTable = new DataTable("Districts ");
adapter.Fill(gchildTable);
ds.Tables.Add(gchildTable);
….

Binding XTreeView is no longer a difficult job to do now. First, you have to take a connection object and open it. Then take a DataSet object and initialize it. Take SQLDataAdapter object and fill the parent table through it. Do not forget to name the table while initializing the DataTable object because it will be used implicitly by the table name property of XTreeView. Then add it to the table collection of the dataset. Repeat the same steps for each next child table. In our case we have three tables, Provinces, Division and Districts. Though populating the dataset with the tables has been accomplished, we are still left with setting the fields’ mandatory relationship properties of the control.

Listing 7

XTreeView1.ParentChildRealtionField = "ProvinceID";
XTreeView1.ChildParentRelationField = "ProvinceID";
XTreeView1.ChildGrandChildRelationField = "DivisionID";
XTreeView1.GrandChildRelationField = "DivisionID";
XTreeView1.DataSet = ds; 

These properties are self explanatory and also have been explained earlier. The important point here is that even programmatically, much of the effort of binding and establishing relationship between tables has been lifted through these properties. You can still use the table text field and table value filed properties which are optional, otherwise default will be used. You can set the table value field property with the field name that contains the corresponding pages path if any (only from root directory or sub folders). In this way, you can take advantage of navigation using database or side-by-side with sitemap. Lastly, you have to set the DataSet property of XTreeView with the populated dataset.

Downloads

Acknowledgments

Lastly, I would like to acknowledge Andrew Robinson’s work for saving TreeView state (available on his blog). This control has benefited from it.

Conclusion

Extended TreeView is of great use when we want to save expansion state and bind it with multiple sitemaps. It can also minimize the effort of writing code for binding a TreeView with database programmatically. It gives us flexibility to have more than one sitemaps in application and bind each of them with a separate instance of XTreeView. It helps us organize site maps into categories and apply, if required, different layout and appearance to each of them.

Although I have tried to provide maximum ease of use and flexibility in this version of Extended TreeView, there is one limitation - binding XTreeView with a database. We can only bind it to three levels, as most of time we need up to three levels. Making it bindable up to n levels would have created complexity. That requires extensibility on TreeNode level. But the properties that work for binding XTreeView with database have been intentionally provided at TreeView level, instead of TreeNode just for sake of simplicity and ease of use, therefore extensibility got compromised. That might be incorporated in some future version of the control. Even in case one requires binding it with more than three levels, he or she can still go for it and can take the advantage of expansion state saving feature (in this case it can be binded with database programmatically, the traditional way). I hope it will work great. Use it and have fun.

Happy TreeViewing!



User Comments

Title: hi   
Name: masoud
Date: 2012-05-28 6:35:45 AM
Comment:
thank for you
Title: hi   
Name: enes
Date: 2011-05-18 8:22:06 AM
Comment:
thats realy good artical thank you .. But when i try with mdb it's not support have can i do ..thanks..
Title: Thanks alot..   
Name: vikram dhawan
Date: 2010-10-20 6:52:17 AM
Comment:
Thanks,i was looking for it the same thing.
God bless you..
keep writing more articles...
thanks again...
Title: Ok   
Name: Alberto
Date: 2010-07-30 4:45:45 PM
Comment:
Hello Mahr
your control is ok but I need it to be strong signed. I have to put the control in sharepoint page and, as you know, sharepoint does not like not signed assembly.
Can you help me?
Thanks
Alberto
Title: Code will not work   
Name: Tiger Woods
Date: 2010-04-06 1:54:17 PM
Comment:
FYI, if you use ImageSet="Simple"
Title: Where is the ExtendedXControls Code?   
Name: OutOfTouch
Date: 2010-02-20 5:43:03 PM
Comment:
Where is the code for the TreeView? All I see is a sample web using the exteneded controls dll?
Title: Expand Node on Mouse over   
Name: Mak
Date: 2008-08-07 5:14:46 PM
Comment:
I need a TreeView who's node will expand on mouse over.

Any View's ??
Title: SelectedIndex   
Name: Mark
Date: 2008-02-18 9:37:57 AM
Comment:
Hi Mahr,
Thanks for the reply. I read the article and it was very helpful in terms of learning the basics on how to extend a control. Thank you. The thing is that with the treeview webcontrol, as you mention in your article, is missing certain mission-critical functionality, such is when posting back it not showing the selected noded in the window, so each time the user has to scroll down. That's crazy-making. I looked at your extendedtreeview.dll in reflector to see if I could figure out how to get it to work properly when I extend the control, but to be honest, I couldn't put it together. Could you help me with this? It would be awesome if you can get me going. The only thing I care about at the moment with treeview is this retarded postback issue. Everything else I have working fine. Thank you!
Title: Re: It Dont Work   
Name: Mahr G. Mohyuddin
Date: 2008-01-26 1:02:32 AM
Comment:
Hi,

You have not read the artcile
You have not used the "value" property for keeping url. DONT use url property.
Title: It Dont Work   
Name: James
Date: 2008-01-25 12:20:29 PM
Comment:
Hi

Downloaded and replaced an existing tree view with yours. Works exactly as existing tree view, that’s the problem, it is not remembering its state.

Is there a website, page or control setting I need to set?
Title: Re: extendedtreeview.dll   
Name: Mahr G. Mohyuddin
Date: 2008-01-17 2:19:41 PM
Comment:
Hi Mark!
My another article "Developing Custom Controls Part 1" has recently been published. You may view it wwww.aspalliance.com/1526. It explains in detail the types of custom cotrols and the steps in detail required to develope custom controls ( extended one in first part , ExtendedTextBox ). although I have not made exended treeview as an example in this yet reading this article will let you know all required steps and their detail for extending any control.
Title: extendedtreeview.dll   
Name: mark
Date: 2008-01-17 8:05:22 AM
Comment:
Hi Mohyuddin,
Very cool. Just wondering, you mention "This article does not explain how to extend a TreeView control. That will be covered in a separate article"... just wondering, have you had a chance to publish that one? If so, could you post a link to it? That would be great. Thanks!
Title: Re: NO SaveExpandedState property   
Name: G. Mohyuddin
Date: 2007-12-06 3:06:40 AM
Comment:
Hi Mike,

Actually the Extended Treeview saves its state by default you won't need set any property. Earlier the property SaveExpandedState was there later it was excluded and I am sorry I could not remove it from article's text.

Do let me know, if you have any concern regarding this.

Regards.
Title: G. Mohyuddin   
Name: Re: Problem
Date: 2007-06-22 6:13:47 AM
Comment:
Hi,

You dont need to look for SaveExpansionState property. By default it supports treeview sate saving. Initially I provided this to turn it off/on but later i intentionally removed from code but forgot to remove it from documentation. use it u dont need to set any property for expansion sate saving.
Title: Problem   
Name: Nick
Date: 2007-06-22 4:21:53 AM
Comment:
Hi Just downloaded this,just what I need, SaveExpansionState, except this feature is missing. I have gone through all the options and cannot find the feature. According to your info above it should be between populatenodesfromclient and showcheckboxes, but it is not there. Help !!!!!
Title: Re: Great Work   
Name: G. Mohyuddin
Date: 2007-05-23 9:12:36 AM
Comment:
Thanks, Amir Mughal!
Title: Great Work   
Name: M Aamir Mughal
Date: 2007-05-23 8:57:13 AM
Comment:
ha!
great work man :)
keep it up ... (Y)
Title: Re:Nice Work   
Name: G. Mohyuddin
Date: 2007-05-23 2:32:35 AM
Comment:
Thanks! Waheed Aslam.
Title: Nice Work   
Name: Waheed Aslam Ghuman
Date: 2007-05-23 2:31:15 AM
Comment:
Great work G. Mohyuddin. Features added to treeview are really very useful and very much desired by most developers

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-29 7:32:08 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search