Nuget Package
ASTreeView is now on Nuget.org. Please install using(for .Net Framework 4.0 and above):
PM> Install-Package ASTreeView
or if you target to .Net Framework 2.0/3.5, using:
PM> Install-Package ASTreeView.Legacy
Introduction
ASTreeView
is a full functional 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 compatible with ASP.NET 2.0 and above.
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!
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;
}
ASTreeView Demo
2. Tree Lines
Enable/Disable tree line is available.
See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo1.aspx.
3. Tree Node Icons
The developer can specify customized icon for each node, use default node icon, or, disable node icon.
See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo1.aspx.
4. Checkbox
Three-state (checked, unchecked, half-checked) checkbox is available.
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.
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
DataTable
See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo4.aspx.
7. Server-side Event Supported
OnSelectedNodeChanged
and OnCheckedNodeChanged
are available.
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.
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;
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.
See live demo
10. ASDropDownTree
ASDropDownTree
inherits ASTreeView
, looks like a DropDownList
, multi-selection and single-selection are available by the control's configuration.
See live demo: http://www.astreeview.com/ASTreeViewDemo/ASTreeViewDemo6.aspx.
11. Drag & Drop Between (or Even Among) Trees
Nodes can be dragged and dropped across trees.
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:
To add your customized menu, it’s easy:
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.3.0, 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.
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:
"_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" ) )
);
15. Themes
ASTreeView
now supports themes! A developer can easily create his own theme for the treeview
. Check out the demo.
Screenshot:
16. Right-To-Left Support
ASTreeView
now supports RTL display, thank Mojtaba Vali for the suggestion! Also check out the demo.
17. HTML as TreeNodeText Supported
In the new version, you may use HTML as tree node text, not only plain text.
18. Multiline Edit Mode Supported
Set the EnableMultiLineEdit
property to enable this feature, the default is false
.
19. Drag and Drop Complete Event Now is Available.
I added a new client side event after drag and drop. to use:
<script type="text/javascript">
function dndHandler( elem ){
document.getElementById( "<%=divConsole.ClientID %>" ).innerHTML
+= ( ">>node dragged:"
+ elem.getAttribute("treeNodeValue")
+ "<br />" );
}
</script>
and then set the OnNodeDragAndDropCompleteScript="dndHandler( elem )"
, visit demo.
Screenshot:
20. New Property for ASTreeViewNode – EnableChildren
Set this property to false
can disable dragging other nodes to the current node as child nodes. Please refer to sample 1 to see the effect.
21. Virtical Drag and Drop Nodes
If you use ASTreeView
as a list, you can set EnableHorizontalLock
to true
, then the end user can only move the nodes up and down, not left nor right.
Screenshot:
22. Fix Drag and Drop Depth
If you want the end user to just move the node within the same level as its original level, you may set the property EnableFixedDepthDragDrop=true
, then the nodes can only be dragged and dropped to the same level as its original level, visit online demo.
23. Add OnNodeDragAndDropStartScript Event
A new event OnNodeDragAndDropStartScript
is now available for developers to execute some JS when the end user start to drag nodes. Here’s a usage sample:
Add a property for astreeview
:
OnNodeDragAndDropStartScript="dndStartHandler( elem )"
The JS function to handle start drag drop:
functiondndStartHandler( elem ){
document.getElementById("").innerHTML
+= (">>drag started. [Node]"+ elem.getAttribute("treeNodeValue")
+" [Parent]:"+ elem.parentNode.parentNode.getAttribute("treeNodeValue")
+"
");
}
24. New node type: TextNode
The content of tree nodes is now more flexible. You can add HTML, JavaScript in the new node type – TextNode
:
Screenshot:
25. Supports Customized JavaScript Handler
For example, if the developer wants to cancel add node action if server returns some specified condition. He can:
- Set
EnableOnNodeAddedScriptReturn="true"
- Set
OnNodeAddedScript="addedHandler(elem)"
- Write the
addedHandler
:
function addedHandler( elem ){
var message = '';
var result = true;
var aTag = elem.getElementsByTagName('A')[0];
if( aTag.getAttribute('addfailed') == 'true' ){
alert( aTag.innerHTML );
return false;
}
else{
message = (">>add completed. [Node]"
+ elem.getAttribute("treeNodeValue") + "<br />" );
}
document.getElementById("").innerHTML
+= message;
return result;
}
In this case, when the server side returns the node with addfailed
in the anchor, the astreeview
will cancel the add action.
The same approach can be applied on Edit, Delete and DragDrop.
Some screenshots:
26. New API added (1.5.8)
New API added in 1.5.8:
SelectNode
– select a node by node value CheckNodes
– check nodes by node values UnCheckNodes
- uncheck nodes by node values FindByValue
– find node by node value, just like the FindControl
in WebControl
FindByText
– find node by node text
27. Enable/Disable feature in ASDropDownTreeView
Developers now can set Enabled
property of ASDropDownTreeView
to enable/disable it.
The configuration in aspx:
this.astvMyTree.Enabled = false;
28. EnableOpenClose property for ASTreeViewNode
It’s now possible to remove the plus/minus icon in front of the tree node. This is for some situation that some nodes are needed to always be open. Just simply set the EnableOpenClose to false to remove the open/close icon:
someNode.EnableOpenClose = false;
29. [IMPORTANT]Drag and Drop API change in 1.5.8
In the new version, I changed the OnNodeDragAndDropCompleteScript
to OnNodeDragAndDropCompletingScript and added a new API called OnNodeDragAndDropCompletedScript.
And the difference between the new APIs:
In OnNodeDragAndDropCompleting
, you CANNOT get the new siblings of the current node because the drag and drop hasn’t finished yet. But you can cancel the drag and drop at this time.
In OnNodeDragAndDropCompleted
, you CANNOT cancel the drag and drop because the node has been appended to the new node. But at this time, you can get the new parent, new sibling of the current node.
If you are going to update to 1.5.8 and you’re using the on node drag and drop event, please update your code, change the OnNodeDragAndDropComplete
to OnNodeDragAndDropCompleting
to keep the same behavior.
Support
In order to manage request in a good manner, I setup a mantis system for submitting requests and bugs. Please find the Mantis link in http://www.astreeview.com/astreeviewdemo/Support.aspx.
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.5.8, visit for details.
In the release 1.5.8, several new features are added:
- New APIs
- Enable/Disable feature in
ASDropDownTreeView
EnableOpenClose
property for ASTreeViewNode
- [IMPORTANT] Drag and Drop API change
In the release 1.5.5, several new features are added:
- Added new API for check, select and find nodes:
SelectNode
, CheckNodes
, UnCheckNodes
, FindByValue
, FindByText
- Added new node type:
TextNode
- Added
EnableDragDropOnIcon
property - Supports customized JavaScript handler
- Improved CSS for
ASTreeView
- Improved
ViewState
Management - Strong Named Assembly
In the release 1.4.0, several new features are added:
- Vertical Drag and Drop Nodes
- Fix Drag and Drop depth
- Add
OnNodeDragAndDropStartScript
Event - Several bugs fixed
In the release 1.3.0, several new features are added:
- Themes
- Right-To-Left support
- HTML as
TreeNodeText
supported - Support escape edit/add input
- Multiline Edit Mode supported
- Drag and drop complete event now is available
- New property for
ASTreeViewNode
– EnableChildren