RadTreeList - Expand Items Stored on Session

1 Answer 21 Views
TreeList
Diego
Top achievements
Rank 1
Diego asked on 24 Oct 2025, 03:12 PM

Hi,

I need to restore the expanded state of a RadTreeList after a redirect. I am storing the expanded items in Session before the redirect. However, server-side expansion only expands the root, not the child items.

Can someone share a JavaScript example or approach to fully expand all previously expanded nodes by the user after a redirect using the stored session data?

If your approach works in Server Side, I will use it on my solution

Thanks team!

This is an example using server side, but it expands only the first root element (not sure why)

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Telerik.Web.UI;

namespace SysMgmt.Groups
{
    public partial class GroupMaintenanceServer : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                RadTreeList1.NeedDataSource += RadTreeList1_NeedDataSource;
            }
        }

        protected void RadTreeList1_NeedDataSource(object sender, TreeListNeedDataSourceEventArgs e)
        {
            RadTreeList1.DataSource = GetData();
        }

        // ✅ Guardar los nodos expandidos antes del render
        protected void Page_PreRender(object sender, EventArgs e)
        {
            var expandedItems = RadTreeList1.Items
                .Where(i => i.Expanded)
                .Select(i => (int)i.GetDataKeyValue("ID"))
                .ToList();

            Session["ExpandedNodes"] = expandedItems;
        }

        protected void RadTreeList1_DataBound(object sender, EventArgs e)
        {
            if (Session["ExpandedNodes"] is List<int> expanded)
            {
                foreach (TreeListDataItem item in RadTreeList1.Items)
                {
                    int id = (int)item.GetDataKeyValue("ID");
                    if (expanded.Contains(id))
                        item.Expanded = true;
                }
            }
        }

        protected void RadTreeList1_ItemCommand(object sender, TreeListCommandEventArgs e)
        {
            if (e.CommandName == "EditItem" && e.Item is TreeListDataItem dataItem)
            {
                int id = (int)dataItem.GetDataKeyValue("ID");
                Response.Redirect($"EditPage.aspx?id={id}");
            }
        }

       
        private DataTable GetData()
        {
            DataTable table = new DataTable();
            table.Columns.Add("ID", typeof(int));
            table.Columns.Add("ParentID", typeof(int));
            table.Columns.Add("Text", typeof(string));
            table.Columns.Add("Value", typeof(string));

            // Root nodes
            table.Rows.Add(1, DBNull.Value, "Root 1", "A");
            table.Rows.Add(2, DBNull.Value, "Root 2", "B");

            // Children of Root 1
            table.Rows.Add(3, 1, "Child 1.1", "A1");
            table.Rows.Add(4, 1, "Child 1.2", "A2");

            // Children of Root 2
            table.Rows.Add(5, 2, "Child 2.1", "B1");
            table.Rows.Add(6, 2, "Child 2.2", "B2");

            // Sub-child
            table.Rows.Add(7, 3, "SubChild 1.1.1", "A1a");

            return table;
        }
    }
}
Katelyn
Top achievements
Rank 1
commented on 12 Nov 2025, 02:24 PM

Hello,

It seems that the issue you're facing is related to expanding child nodes after a redirect, despite storing the expanded state in the session. The code you've shared for server-side expansion works for root items but doesn't account for the hierarchical structure of child and sub-child items. Here's a suggestion to fully expand the tree, including child nodes, based on the stored session data.

Approach:

Modify the RadTreeList1_DataBound method:
You need to ensure that when restoring the expanded state, the child nodes are properly expanded by recursively checking all levels of the tree.

Ensure Hierarchical Expansion:
To fully expand all nodes (root and child), the logic should traverse the tree structure and restore the expanded state for each item, including its children.

Here is an enhanced approach using a recursive method to handle expansion for all levels:

 

protected void RadTreeList1_DataBound(object sender, EventArgs e)
{
    if (Session["ExpandedNodes"] is List<int> expanded)
    {
        // Recursively expand nodes based on session data
        foreach (TreeListDataItem item in RadTreeList1.Items)
        {
            ExpandItemRecursive(item, expanded);
        }
    }
}

private void ExpandItemRecursive(TreeListDataItem item, List<int> expanded)
{
    int id = (int)item.GetDataKeyValue("ID");
    if (expanded.Contains(id))
    {
        item.Expanded = true;
    }

    // Expand children recursively
    foreach (TreeListDataItem childItem in item.Items)
    {
        ExpandItemRecursive(childItem, expanded);
    }
}

 

Explanation:

ExpandItemRecursive:
This method checks if the current node (and its children) should be expanded by matching its ID with the list of expanded nodes stored in the session.

RadTreeList1_DataBound:
Loops through the root items and applies the ExpandItemRecursive method to ensure all child items are expanded correctly.

Additional Considerations:

Session Management: Make sure that the session data (Session["ExpandedNodes"]) persists correctly across redirects. If there are issues with session state (e.g., across different browsers or sessions), verify that the session management is correctly configured.

Performance: If the tree structure is large, ensure that expanding many levels doesn't impact the performance negatively. You can optimize the process by limiting the number of nodes expanded at once or using lazy loading for child nodes.

By applying this recursive method, you should be able to expand all previously expanded nodes, including child and sub-child nodes, after the redirect.

I hope this helps!

1 Answer, 1 is accepted

Sort by
0
Leslie
Top achievements
Rank 1
Iron
answered on 30 Oct 2025, 10:03 AM

Hello,

You can restore all levels by calling Rebind() and using the correct order of operations. Restore expanded state after binding (in PreRenderComplete) and ensure parent items are expanded before children. Use recursive logic for hierarchical structures.

Here’s the adjusted code:


using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Telerik.Web.UI;

namespace SysMgmt.Groups
{
    public partial class GroupMaintenanceServer : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            RadTreeList1.NeedDataSource += RadTreeList1_NeedDataSource;
            RadTreeList1.DataBound += RadTreeList1_DataBound;

            if (!IsPostBack)
            {
                RadTreeList1.Rebind();
            }
        }

        protected void RadTreeList1_NeedDataSource(object sender, TreeListNeedDataSourceEventArgs e)
        {
            RadTreeList1.DataSource = GetData();
        }

        // ✅ Store expanded nodes before render
        protected void Page_PreRender(object sender, EventArgs e)
        {
            var expandedItems = RadTreeList1.Items
                .Where(i => i.Expanded)
                .Select(i => (int)i.GetDataKeyValue("ID"))
                .ToList();

            Session["ExpandedNodes"] = expandedItems;
        }

        // ✅ Restore all expansions after full binding
        protected void RadTreeList1_DataBound(object sender, EventArgs e)
        {
            if (Session["ExpandedNodes"] is List<int> expanded)
            {
                foreach (TreeListDataItem item in RadTreeList1.Items)
                {
                    int id = (int)item.GetDataKeyValue("ID");
                    if (expanded.Contains(id))
                        item.Expanded = true;
                }
            }
        }

        protected void RadTreeList1_ItemCommand(object sender, TreeListCommandEventArgs e)
        {
            if (e.CommandName == "EditItem" && e.Item is TreeListDataItem dataItem)
            {
                int id = (int)dataItem.GetDataKeyValue("ID");
                Response.Redirect($"EditPage.aspx?id={id}");
            }
        }

        private DataTable GetData()
        {
            DataTable table = new DataTable();
            table.Columns.Add("ID", typeof(int));
            table.Columns.Add("ParentID", typeof(int));
            table.Columns.Add("Text", typeof(string));
            table.Columns.Add("Value", typeof(string));

            // Root nodes
            table.Rows.Add(1, DBNull.Value, "Root 1", "A");
            table.Rows.Add(2, DBNull.Value, "Root 2", "B");

            // Children of Root 1
            table.Rows.Add(3, 1, "Child 1.1", "A1");
            table.Rows.Add(4, 1, "Child 1.2", "A2");

            // Children of Root 2
            table.Rows.Add(5, 2, "Child 2.1", "B1");
            table.Rows.Add(6, 2, "Child 2.2", "B2");

            // Sub-child
            table.Rows.Add(7, 3, "SubChild 1.1.1", "A1a");

            return table;
        }
    }
}

Tags
TreeList
Asked by
Diego
Top achievements
Rank 1
Answers by
Leslie
Top achievements
Rank 1
Iron
Share this question
or