Click here to Skip to main content
6,630,289 members and growing! (23,666 online)
Email Password   helpLost your password?
Web Development » ASP.NET Controls » General License: The Code Project Open License (CPOL)

ASTreeView - A Powerful ASP.NET TreeView Control

By JIN Weijie

A full functional treeview control for ASP.NET, including drag and drop, Ajax loading, context menu, dropdown treeview.
C#, Javascript, Windows, ASP.NET, Ajax, Dev
Version:7 (See All)
Posted:14 Oct 2009
Updated:22 Oct 2009
Views:10,622
Bookmarked:85 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
49 votes for this article.
Popularity: 7.95 Rating: 4.71 out of 5
1 vote, 2.0%
1

2
3 votes, 6.1%
3
3 votes, 6.1%
4
42 votes, 85.7%
5

Introduction

ASTreeView is a powerful treeview control for ASP.NET with drag drop, Ajax loading, context menu, XML import/export, checkbox, selection, adding/editing/deleting nodes with Ajax.

Background

ASTreeView is developed on .NET Framework 2.0. The demo project is a Visual Studio 2005 project.

ASTreeView is FREE! That means you can use it anywhere!

I host the project on Google Code: please download the assembly and the demo, check out the demo, and use ASTreeView in your project!

Updated

I registered a domain name for astreeview: http://www.astreeview.com.

Using the Code

Here are functionalities ASTreeView supports:

1. Drag & Drop

User can drag & drop nodes within the tree or even among trees!

astreeview_intro_1

See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo1.aspx.

 <ct:ASTreeView ID="astvMyTree" 
	runat="server"
	BasePath="~/Javascript/astreeview/"
	DataTableRootNodeValue="0"
	EnableRoot="false" 
	EnableNodeSelection="false" 
	EnableCheckbox="true" 
	EnableDragDrop="true" 
	EnableTreeLines="true"
	EnableNodeIcon="true"
	EnableCustomizedNodeIcon="true"
	EnableContextMenu="true"
	EnableDebugMode="false"
	EnableContextMenuAdd="false" />  
In Code Behind
protected void btnToggleDragDrop_Click( object sender, EventArgs e )
{
	this.astvMyTree.EnableDragDrop = !this.astvMyTree.EnableDragDrop;
}

protected void btnToggleTreeLines_Click( object sender, EventArgs e )
{
	this.astvMyTree.EnableTreeLines = !this.astvMyTree.EnableTreeLines;
}

protected void btnToggleNodeIcon_Click( object sender, EventArgs e )
{
	this.astvMyTree.EnableNodeIcon = !this.astvMyTree.EnableNodeIcon;
}

protected void btnToggleCheckbox_Click( object sender, EventArgs e )
{
	this.astvMyTree.EnableCheckbox = !this.astvMyTree.EnableCheckbox;
}

protected void btnToggleDefaultNodeIcon_Click( object sender, EventArgs e )
{
	this.astvMyTree.EnableCustomizedNodeIcon = 
			!this.astvMyTree.EnableCustomizedNodeIcon;
}

protected void btnToggleContextMenu_Click( object sender, EventArgs e )
{
	this.astvMyTree.EnableContextMenu = !this.astvMyTree.EnableContextMenu;
} 

2. Tree Lines

Enable/Disable tree line is available.

astreeview_intro_2

See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo1.aspx.

3. Tree Node Icons

The developer can specific customized icon for each node, use default node icon, or, disable node icon.

astreeview_intro_3

See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo1.aspx.

4. Checkbox

Three-state (checked, unchecked, half-checked) checkbox is available.

astreeview_intro_4

See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo1.aspx.

5. Tree Node Context Menu

A user can use context menu to edit/delete node by right clicking the node. Ajax edit/delete is supported.

astreeview_intro_5

See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo3.aspx.

6. Multi-data Source Supported

A developer can bind different types of data source (currently astreeview supports datatable and XML datasource). Or developer can create ASTreeViewNode and append to the tree in the code.

XML

astreeview_intro_6

DataTable

astreeview_intro_6-2

See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo4.aspx.

7. Server-side Event Supported

OnSelectedNodeChanged and OnCheckedNodeChanged are available.

astreeview_intro_7

See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo2.aspx.

Configuration
  <ct:ASTreeView ID="astvMyTree" 
	runat="server"
	BasePath="~/Javascript/astreeview/"
	DataTableRootNodeValue="0"
	EnableRoot="false" 
	EnableNodeSelection="true" 
	EnableCheckbox="true" 
	EnableDragDrop="false" 
	EnableTreeLines="true"
	EnableNodeIcon="true"
	EnableCustomizedNodeIcon="false"
	AutoPostBack="true"
	EnableDebugMode="false"
	EnableContextMenu="false"
	OnOnCheckedNodeChanged="astvMyTree_OnCheckedNodeChanged" 
	OnOnSelectedNodeChanged="astvMyTree_OnSelectedNodeChanged" />
In Code Behind
protected void astvMyTree_OnCheckedNodeChanged
	( object src, ASTreeViewNodeCheckedEventArgs e )
{
	string toConsole = string.Format( ">>OnCheckedNodeChanged checked: 
		text:{0} value:{1} state:{2}", e.NodeText, e.NodeValue, 
		e.CheckedState.ToString() );
	this.divConsole.InnerHtml += ( toConsole + "<br />" );
}

protected void astvMyTree_OnSelectedNodeChanged( object src, 
				ASTreeViewNodeSelectedEventArgs e )
{
	string toConsole = string.Format( ">>OnSelectedNodeChanged selected: 
		text:{0} value:{1}", e.NodeText, e.NodeValue );
	this.divConsole.InnerHtml += ( toConsole + "<br />" );
}

protected void btnGetSelectedNode_Click( object sender, EventArgs e )
{
	string toConsole = string.Empty;

	ASTreeViewNode selectedNode = astvMyTree.GetSelectedNode();
	if( selectedNode == null )
		toConsole = ">>no node selected.";
	else
		toConsole = string.Format( ">>node selected: text:{0} value:{1}", 
			selectedNode.NodeText, selectedNode.NodeValue );

	this.divConsole.InnerHtml += ( toConsole + "<br />" );
}

protected void btnGetCheckedNodes_Click( object sender, EventArgs e )
{
	List<ASTreeViewNode> checkedNodes = this.astvMyTree.GetCheckedNodes
			( cbIncludeHalfChecked.Checked );
	StringBuilder sb = new StringBuilder();

	foreach( ASTreeViewNode node in checkedNodes )
		sb.Append( string.Format( "[text:{0}, value:{1}]<br />", 
			node.NodeText, node.NodeValue ) );

	this.divConsole.InnerHtml += ( string.Format( ">>nodes checked: 
		<div style='padding-left:20px;'>{0}</div>", sb.ToString() ) );
} 

8. Ajax Nodes Loading Supported

Having thousands of nodes? No problem, ASTreeView supports loading nodes using Ajax.

astreeview_intro_8

See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo5.aspx.

Configuration
<ct:ASTreeView ID="astvMyTree" 
	runat="server"
	BasePath="~/Javascript/astreeview/"
	DataTableRootNodeValue="0"
	EnableRoot="false" 
	EnableNodeSelection="true" 
	EnableCheckbox="true" 
	EnableDragDrop="false" 
	EnableTreeLines="true"
	EnableNodeIcon="true"
	EnableCustomizedNodeIcon="false"
	EnableContextMenu="true"
	EnableDebugMode="false" 
	EnableAjaxOnEditDelete="true"
	AddNodeProvider="~/ASTreeViewDemo5.aspx"
	AdditionalAddRequestParameters="{'t2':'ajaxAdd'}"
	EditNodeProvider="~/ASTreeViewRenameNodeHandler.aspx"
	DeleteNodeProvider="~/ASTreeViewDeleteNodeProvider.aspx"
	LoadNodesProvider="~/ASTreeViewDemo5.aspx"
	AdditionalLoadNodesRequestParameters="{'t1':'ajaxLoad'}"/> 
In Code Behind
protected override void Render( HtmlTextWriter writer )
{
	if( Request.QueryString["t1"] == "ajaxLoad" )
	{
		string virtualParentKey = Request.QueryString["virtualParentKey"];

		string para = string.Empty;// "= 1";
		if( virtualParentKey == null )
			para = " is NULL";
		else
			para = "=" + virtualParentKey;

		string sql = @"SELECT p1.[ProductID] as 
		    ProductID, p1.[ProductName] as ProductName, 
		    p1.[ParentID] as ParentID, p3.childNodesCount as ChildNodesCount
FROM [Products] p1
LEFT OUTER JOIN 
(
	SELECT COUNT(*) AS childNodesCount , p2.[ParentID] AS pId 
	FROM [Products] p2
	GROUP BY p2.[ParentID]
) p3
ON p1.[ProductID] = p3.pId
WHERE p1.[ParentID] " + para;

DataTable dt = OleDbHelper.ExecuteDataset( base.NorthWindConnectionString, 
	CommandType.Text, sql ).Tables[0];

ASTreeViewNode root = new ASTreeViewNode( "root" );

foreach( DataRow dr in dt.Rows )
{
	string productName = dr["ProductName"].ToString();
	string productId = dr["ProductID"].ToString();
	string parentId = dr["ParentID"].ToString();
	int childNodesCount = 0;
	if( !string.IsNullOrEmpty( dr["ChildNodesCount"].ToString() ) )
		childNodesCount = int.Parse( dr["ChildNodesCount"].ToString() );

	ASTreeViewLinkNode node = new ASTreeViewLinkNode( productName, productId );
	node.VirtualNodesCount = childNodesCount;
	node.VirtualParentKey = productId;
	node.IsVirtualNode = childNodesCount > 0;
	node.NavigateUrl = "#";
	node.AddtionalAttributes.Add( new KeyValuePair<string, string>
			( "onclick", "return false;" ) );

	root.AppendChild( node );
}

HtmlGenericControl ulRoot = new HtmlGenericControl( "ul" );
astvMyTree.TreeViewHelper.ConvertTree( ulRoot, root, false );
foreach( Control c in ulRoot.Controls )
	c.RenderControl( writer );
}
else if( Request.QueryString["t2"] == "ajaxAdd" )
{
	string addNodeText = Request.QueryString["addNodeText"];
	int parentNodeValue = int.Parse( Request.QueryString["parentNodeValue"] );

	string maxSql = "select max( productId ) from products";
	int max = (int)OleDbHelper.ExecuteScalar
		( base.NorthWindConnectionString, CommandType.Text, maxSql );
	int newId = max + 1;

	string sql = string.Format( @"INSERT INTO products
	( productid, Discontinued, productname, parentid ) values( {0} ,0, '{1}', {2})"
	, max + 1, addNodeText.Replace( "'", "''" ), parentNodeValue );

	int i = OleDbHelper.ExecuteNonQuery
		( base.NorthWindConnectionString, CommandType.Text, sql );

	ASTreeViewNode root = new ASTreeViewNode( "root" );

	ASTreeViewLinkNode node = new ASTreeViewLinkNode
				( addNodeText, newId.ToString() );
	node.NavigateUrl = "#";
	node.AddtionalAttributes.Add( new KeyValuePair<string, 
			string>( "onclick", "return false;" ) );

	root.AppendChild( node );

	HtmlGenericControl ulRoot = new HtmlGenericControl( "ul" );
	astvMyTree.TreeViewHelper.ConvertTree( ulRoot, root, false );
	foreach( Control c in ulRoot.Controls )
		c.RenderControl( writer );
}
else
	base.Render( writer );			
} 

9. Multi-type Tree Node

A tree node can be a hyper-link or LinkButton to perform postback.

astreeview_intro_9

See live demo

10. ASDropDownTree

ASDropDownTree inherits ASTreeView, looks like a DropDownList, multi-selection and single-selection are available by the control's configuration.

astreeview_intro_10

See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo6.aspx.

11. Drag & Drop Between (or Even Among) Trees

Nodes can be dragged and dropped cross trees.

astreeview_intro_11

See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo7.aspx.

12. Extending ContextMenu

Now it is possible to add your customized ContextMenu Items to the menu. A screenshot:
image

To add your customized menu, it’s easy:

/// <summary>
/// initial controls, bind you events etc. here
/// </summary>
private void InitializeComponent()
{
    this.astvMyTree.ContextMenu.MenuItems.Add( new ASContextMenuItem( 
        "Custom Menu 1", "alert('current value:' + " 
        + this.astvMyTree.ContextMenuClientID
        + ".getSelectedItem().parentNode.getAttribute('treeNodeValue')" 
        + ");return false;", "otherevent" ) );

    this.astvMyTree.ContextMenu.MenuItems.Add( new ASContextMenuItem( 
        "Custom Menu 2", "alert('current text:' + " 
        + this.astvMyTree.ContextMenuClientID 
        + ".getSelectedItem().innerHTML" 
        + ");return false;", "otherevent" ) );
}

Online demo: http://www.astreeview.com/astreeviewdemo/ASTreeViewDemo3.aspx.

13. Extending ContextMenu

In version 1.1.2, the end user can open the folder by clicking on the node text. It is useful when only the leaf nodes are clickable, for example, bookmarks.

image

To enable this feature, just set the “EnableParentNodeExpand” property of ASTreeView.

14. Customize Node with HTML

NodeText can be HTML:

 this.astvMyTree.RootNode
.AppendChild( new ASTreeViewLinkNode
	( "Accor <a href='http://www.astreeview.com' target='_blank'>see demo</a>"
, "Accor"
, "http://www.accor.com", "_self", "Goto Accor", "~/Images/demoIcons/accor.gif" )
	.AppendChild( new ASTreeViewLinkNode( "Accor Services", 
	"Accor Services", http://www.accorservices.com, 
	"_self", "Goto Accor Services", "~/Images/demoIcons/accorservices.gif" ) )
	.AppendChild( new ASTreeViewLinkNode( "Accor Hospitality", 
	"Accor Hospitality", "http://www.accorhotels.com", "_self", 
	"Goto Accor Hospitality", "~/Images/demoIcons/accorhospitality.gif" ) )
); 

Points of Interest

I spent two or three months in development, and the ASTreeView is finally finished. Now I would like to introduce it to you. Your feedback is appreciated!

History

The current version of ASTreeView is 1.1.2, visit for details.

In the release 1.1.2, two new features are added:

  1. Extending ContextMenu
  2. Expand node by clicking node text

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

JIN Weijie


Member
ASTreeView, the best FREE treeview control for ASP.NET.
Occupation: Software Developer (Senior)
Company: Accor Services China
Location: China China

Other popular ASP.NET Controls articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 69 (Total in Forum: 69) (Refresh)FirstPrevNext
Generalsome nodes are single choice, some are mult-choice PinmemberMember 54115712:40 17 Nov '09  
GeneralRe: some nodes are single choice, some are mult-choice PinmemberJIN Weijie15:47 17 Nov '09  
Generaldropdownlist as node of treeview PinmemberMember 5411576:43 17 Nov '09  
GeneralRe: dropdownlist as node of treeview PinmemberJIN Weijie15:46 17 Nov '09  
GeneralNo words, just a 5 star for a brilliant job! Pinmembersonyatan14:57 14 Nov '09  
GeneralRe: No words, just a 5 star for a brilliant job! PinmemberJIN Weijie22:12 16 Nov '09  
GeneralHow to save changes to xml file after edit/delete/add PinmemberKaeghl9:51 12 Nov '09  
GeneralRe: How to save changes to xml file after edit/delete/add PinmemberJIN Weijie22:11 16 Nov '09  
GeneralLooks great PinassociateAbhishek Sur22:39 11 Nov '09  
GeneralRe: Looks great PinmemberJIN Weijie22:09 16 Nov '09  
GeneralBackColor property not working? Pinmemberchris b.23:22 8 Nov '09  
GeneralRe: BackColor property not working? PinmemberJIN Weijie22:09 16 Nov '09  
Question'_rdc' is undefined Pinmembertarek_shawadfy7:34 5 Nov '09  
AnswerRe: '_rdc' is undefined PinmemberJIN Weijie7:50 5 Nov '09  
AnswerRe: '_rdc' is undefined PinmemberKaeghl9:23 12 Nov '09  
Generalsaving tree structure after reorder Pinmemberjlschumann7:40 3 Nov '09  
GeneralRe: saving tree structure after reorder PinmemberJIN Weijie18:35 3 Nov '09  
Generaladd nodes without databinding? PinmemberMojtaba Vali4:03 2 Nov '09  
GeneralRe: add nodes without databinding? PinmemberJIN Weijie8:53 2 Nov '09  
GeneralVery good but small problem PinmemberAdamRae4:09 30 Oct '09  
GeneralRe: Very good but small problem PinmemberAdamRae4:30 30 Oct '09  
GeneralRe: Very good but small problem PinmemberJIN Weijie4:44 30 Oct '09  
GeneralImg Url Property problem.. Pinmembertzess22:53 29 Oct '09  
GeneralRe: Img Url Property problem.. PinmemberJIN Weijie23:07 29 Oct '09  
GeneralRe: Img Url Property problem.. PinmemberJIN Weijie23:56 29 Oct '09  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 22 Oct 2009
Editor: Deeksha Shenoy
Copyright 2009 by JIN Weijie
Everything else Copyright © CodeProject, 1999-2009
Web10 | Advertise on the Code Project