Consider the following scenario:
- There is a treeview on the page
- The treeview is bound to a SQL database and the TreeNodes have unique values - it is important that the nodes have unique values so that the task can be achieved
- Tree-nodes use ExpandMode.ServerSideCallBack
- There is a button on the page
The following should be achieved:
When a postback appears upon a button click the expanded state of the nodes should be persisted afterwards.
Example:
| ASPX | |
|---|---|
<rad:radtreeview id="RadTreeView1" runat="server" OnNodeExpand="RadTreeView1_NodeExpand"> </rad:radtreeview> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" /> | |
| C# | |
|---|---|
private DataTable GetNodeData(string query) { OleDbConnection dbCon = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("~/Nodes.mdb")); dbCon.Open(); OleDbDataAdapter adapter = new OleDbDataAdapter(query, dbCon); DataTable dt = new DataTable(); adapter.Fill(dt); dbCon.Close(); return dt; } private void LoadRootNodes() { RadTreeView1.Nodes.Clear(); Session.Remove("expandedNodes"); DataTable dt = GetNodeData("SELECT * FROM Nodes WHERE ParentId IS NULL"); foreach (DataRow row in dt.Rows) { RadTreeNode node = new RadTreeNode(); node.Text = (string)row["Text"]; node.Value = ((int)row["Id"]).ToString(); node.Category = "Some Category"; node.ExpandMode = ExpandMode.ServerSideCallBack; RadTreeView1.Nodes.Add(node); } } private void AddChildNodes(RadTreeNode node) { string sql = "SELECT Nodes.Id AS NodeId, Nodes.Text AS NodeText, COUNT(Children.Id) AS HasChildren FROM Nodes LEFT JOIN Nodes Children ON Nodes.Id = Children.ParentId WHERE Nodes.ParentId = {0} GROUP BY Nodes.Id, Nodes.Text"; sql = String.Format(sql, node.Value); DataTable dt = GetNodeData(sql); foreach (DataRow row in dt.Rows) { RadTreeNode childNode = new RadTreeNode(); childNode.Text = (string)row["NodeText"]; childNode.Value = ((int)row["NodeId"]).ToString(); childNode.Target = "_new"; if (((int)row["HasChildren"]) > 0) { childNode.ExpandMode = ExpandMode.ServerSideCallBack; } node.Nodes.Add(childNode); } } protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack && !RadTreeView1.IsCallBack) { LoadRootNodes(); Session["treeViewState"] = RadTreeView1.GetXml(); } } protected void RadTreeView1_NodeExpand(object o, Telerik.WebControls.RadTreeNodeEventArgs e) { AddChildNodes(e.NodeClicked); string treeViewState = (string) Session["treeViewState"]; RadTreeView cachedTreeView = new RadTreeView(); cachedTreeView.LoadXmlString(treeViewState); //it is important that the nodes have unique values so that they can be added to the cached treeview RadTreeNode cachedNodeClicked = cachedTreeView.FindNodeByValue(e.NodeClicked.Value); AddChildNodes(cachedNodeClicked); cachedNodeClicked.ExpandMode = ExpandMode.ClientSide; cachedNodeClicked.Expanded = true; Session["treeViewState"] = cachedTreeView.GetXml(); } protected void Button1_Click(object sender, EventArgs e) { string treeViewState = (string)Session["treeViewState"]; RadTreeView1.LoadXmlString(treeViewState); } | |
| VB.NET | |
|---|---|
Private Function GetNodeData(ByVal query As String) As DataTable Dim dbCon As OleDbConnection = New OleDbConnection(("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("~/Nodes.mdb"))) dbCon.Open Dim adapter As OleDbDataAdapter = New OleDbDataAdapter(query, dbCon) Dim dt As DataTable = New DataTable adapter.Fill(dt) dbCon.Close Return dt End Function Private Sub LoadRootNodes() RadTreeView1.Nodes.Clear Session.Remove("expandedNodes") Dim dt As DataTable = GetNodeData("SELECT * FROM Nodes WHERE ParentId IS NULL") For Each row As DataRow In dt.Rows Dim node As RadTreeNode = New RadTreeNode node.Text = CType(row("Text"),String) node.Value = CType(row("Id"),Integer).ToString node.Category = "Some Category" node.ExpandMode = ExpandMode.ServerSideCallBack RadTreeView1.Nodes.Add(node) Next End Sub Private Sub AddChildNodes(ByVal node As RadTreeNode) Dim sql As String = "SELECT Nodes.Id AS NodeId, Nodes.Text AS NodeText, COUNT(Children.Id) AS HasChildren FROM Nodes LEFT "& _ "JOIN Nodes Children ON Nodes.Id = Children.ParentId WHERE Nodes.ParentId = {0} GROUP BY Nodes.Id, No"& _ "des.Text" sql = String.Format(sql, node.Value) Dim dt As DataTable = GetNodeData(sql) For Each row As DataRow In dt.Rows Dim childNode As RadTreeNode = New RadTreeNode childNode.Text = CType(row("NodeText"),String) childNode.Value = CType(row("NodeId"),Integer).ToString childNode.Target = "_new" If (CType(row("HasChildren"),Integer) > 0) Then childNode.ExpandMode = ExpandMode.ServerSideCallBack End If node.Nodes.Add(childNode) Next End Sub Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) If (Not Page.IsPostBack _ AndAlso Not RadTreeView1.IsCallBack) Then LoadRootNodes Session("treeViewState") = RadTreeView1.GetXml End If End Sub Protected Sub RadTreeView1_NodeExpand(ByVal o As Object, ByVal e As Telerik.WebControls.RadTreeNodeEventArgs) AddChildNodes(e.NodeClicked) Dim treeViewState As String = CType(Session("treeViewState"),String) Dim cachedTreeView As RadTreeView = New RadTreeView cachedTreeView.LoadXmlString(treeViewState) 'it is important that the nodes have unique values so that they can be added to the cached treeview Dim cachedNodeClicked As RadTreeNode = cachedTreeView.FindNodeByValue(e.NodeClicked.Value) AddChildNodes(cachedNodeClicked) cachedNodeClicked.ExpandMode = ExpandMode.ClientSide cachedNodeClicked.Expanded = true Session("treeViewState") = cachedTreeView.GetXml End Sub Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Dim treeViewState As String = CType(Session("treeViewState"),String) RadTreeView1.LoadXmlString(treeViewState) End Sub | |
Original Source is : http://www.telerik.com/help/aspnet/treeview/tree_store_expanded_callback.html