Click here to Skip to main content
15,505,786 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I had a treeview in my master page, After i expand the treeview and click the node, it will redirect to another page, and then the treeview will be refresh to default, which means showing the treeview before expanding..

What I have tried:

So i need to save the treeview state in order to remain the treeview state. i had tried the below method but it's not working, anyone can help..

protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Session["ExpandedNodes"] != null)
{
((List<string>)Session["ExpandedNodes"]).ForEach(a => TreeView1.FindNode(a).Expanded = true);
}
LoadTransactionMenu();
}
}
private void LoadTransactionMenu()
{
//TRANSACTION MENU // this is used to bind the data to the treeview
string SubModuleID, SubModuleNM, DocModuleID, DocModuleName, MenuTransID, MenuTransName;
SqlConnection con = new SqlConnection(ConString);
string CmdString = "SELECT SUBMODULEID, SUBMODULENM, URLNAME FROM SUBMODULE";
SqlCommand cmd = new SqlCommand(CmdString, con);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
TreeNode node1 = new TreeNode();
node1.Text = "TRANSACTION MENU";
TreeView1.Nodes.Add(node1);
for (int i = 0; i < dt.Rows.Count; i++)
{
SubModuleID = dt.Rows[i]["SUBMODULEID"].ToString();
SubModuleNM = dt.Rows[i]["SUBMODULENM"].ToString();
TreeNode SubModuleNode = new TreeNode(SubModuleNM, SubModuleID);
SubModuleNode.NavigateUrl = dt.Rows[i]["URLNAME"].ToString();
node1.ChildNodes.Add(SubModuleNode);
CmdString = "SELECT DDID, DOCNAME, DDADDRESS FROM DOCMODULE WHERE SUBMODULEID=@SUBMODULEID";
cmd = new SqlCommand(CmdString, con);
cmd.Parameters.AddWithValue("@SUBMODULEID", SubModuleID);
sda = new SqlDataAdapter(cmd);
DataTable dt2 = new DataTable();
sda.Fill(dt2);
for (int j = 0; j < dt2.Rows.Count; j++)
{
DocModuleID = dt2.Rows[j]["DDID"].ToString();
DocModuleName = dt2.Rows[j]["DOCNAME"].ToString();
TreeNode DocModuleNode = new TreeNode(DocModuleName, DocModuleID);
DocModuleNode.NavigateUrl = dt2.Rows[j]["DDADDRESS"].ToString();
SubModuleNode.ChildNodes.Add(DocModuleNode);
CmdString = "SELECT DID, DNAME, DADDRESS FROM MENUTRANSACTION WHERE DDID=@DDID AND UID= '" + Session["UserID"] + "'";
cmd = new SqlCommand(CmdString, con);
cmd.Parameters.AddWithValue("@DDID", DocModuleID);
sda = new SqlDataAdapter(cmd);
DataTable dt3 = new DataTable();
sda.Fill(dt3);
for (int k = 0; k < dt3.Rows.Count; k++)
{
MenuTransID = dt3.Rows[k]["DID"].ToString();
MenuTransName = dt3.Rows[k]["DNAME"].ToString();
TreeNode MenuTransNode = new TreeNode(MenuTransName, MenuTransID);
MenuTransNode.NavigateUrl = dt3.Rows[k]["DADDRESS"].ToString();
DocModuleNode.ChildNodes.Add(MenuTransNode);
}
if (DocModuleNode.ChildNodes.Count == 0)
{
SubModuleNode.ChildNodes.Remove(DocModuleNode);
}
}
if (SubModuleNode.ChildNodes.Count == 0)
{
node1.ChildNodes.Remove(SubModuleNode);
}
}
} 
 
protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
{
List<string> expandedNodes = new List<string>();
//get all expanded nodes
TreeView1.Nodes.Cast<TreeNode>().ToList().ForEach(a => GetExpandedStatus(a, expandedNodes));
//collapse all to reset the treeview
TreeView1.CollapseAll();
//save expanded node value paths
Session["ExpandedNodes"] = expandedNodes;
}
 
public void GetExpandedStatus(TreeNode node, List<string> ExpandedNodes)
{
//check if node is expanded
if (node.Expanded.GetValueOrDefault(false))
ExpandedNodes.Add(node.ValuePath);
node.ChildNodes.Cast<TreeNode>().ToList().ForEach(a => GetExpandedStatus(a, ExpandedNodes));
}
Posted
Updated 4-Apr-21 21:56pm

When you record the expanded states the sub-nodes are listed as expanded even if the parent node is collapsed so that is forcing them all open. This update will ignore the child items of collapsed nodes

C#
public void GetExpandedStatus(TreeNode node, List<string> ExpandedNodes)
{
    //check if node is expanded
    if (node.Expanded.GetValueOrDefault(false))
    {
        ExpandedNodes.Add(node.ValuePath);
        node.ChildNodes.Cast<TreeNode>().ToList().ForEach(a => GetExpandedStatus(a, ExpandedNodes));
    }
}


Also in the page load you set the state of the previously expanded nodes before they are loaded into the tree, so put LoadTransactionMenu first. I also collapsed all nodes before expanding the ones that need to be expanded.

C#
if (!Page.IsPostBack)
{
    LoadTransactionMenu();
    if (Session["ExpandedNodes"] != null)
    {
        TreeView1.CollapseAll();
        ((List<string>)Session["ExpandedNodes"]).ForEach(a => TreeView1.FindNode(a).Expanded = true);
    }
}
 
Share this answer
 
v2
Comments
Member 15095035 5-Apr-21 2:57am    
I had used another method to get it done, but facing another small issue which is after i close the program and run again, the treeview showing the state before i close the program.. i need the state to be default which is all collapse..how to solve it..

In master page .aspx

window.onbeforeunload = function () {
try {
// The expanded state of the treeview is available in the hidden input
// ..._ExpandState. Store that string in a cookie so we have it on the server
// side when the page is loaded in order to restore the state of the treeview.
var expInfo = document.getElementById('<%=TreeView1.ClientID%>' + '_ExpandState');
if (expInfo)
{
createCookie('ToolsTVExpand', expInfo.value, 365);
}
}
catch (err) {
// Ignore the error
}
}
function createCookie(name, value, days) {
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
}
else var expires = "";
document.cookie = name + "=" + value + expires + "; path=/";
}


In behind code :

<protected void="" page_load(object="" sender,="" eventargs="" e)
{
="" if="" (!ispostback)
="" reloadtreeviewstate();
}
public="" reloadtreeviewstate()
{
="" try
="" {
="" httpcookie="" cookie="Request.Cookies[" toolstvexpand"];
"="" (cookie="" !="null" &amp;&amp;="" cookie.value="" int="" curridx="0;
" foreach="" (treenode="" mainnode="" in="" treeview1.nodes)
="" cookie.value,="" curridx);
="" }
="" catch="" (exception="" e)
="" just="" keep="" going
="" }
}
protected="" setnodestates(treenode="" node,="" string="" stateinfo,="" curridx)
{
="" (curridx="">= stateInfo.Length)
throw new Exception("State info shorter than list of nodes.");
Char state = stateInfo[currIdx];enter code here
if (state == 'e')
{
node.Expand();
}
currIdx++;
if (node.ChildNodes != null && node.ChildNodes.Count != 0)
{
foreach (TreeNode childNode in node.ChildNodes)
{
currIdx = setNodeStates(childNode, stateInfo, currIdx);
}
}
return currIdx;

}
I had used another method to get it done, but facing another small issue which is after i close the program and run again, the treeview showing the state before i close the program.. i need the state to be default which is all collapse..how to solve it..

In master page .aspx

window.onbeforeunload = function () {
try {
// The expanded state of the treeview is available in the hidden input
// ..._ExpandState. Store that string in a cookie so we have it on the server
// side when the page is loaded in order to restore the state of the treeview.
var expInfo = document.getElementById('<%=TreeView1.ClientID%>' + '_ExpandState');
if (expInfo)
{
createCookie('ToolsTVExpand', expInfo.value, 365);
}
}
catch (err) {
// Ignore the error
}
}
function createCookie(name, value, days) {
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
}
else var expires = "";
document.cookie = name + "=" + value + expires + "; path=/";
}


In behind code :

<protected void="" page_load(object="" sender,="" eventargs="" e)
{
="" if="" (!ispostback)
="" reloadtreeviewstate();
}
public="" reloadtreeviewstate()
{
="" try
="" {
="" httpcookie="" cookie="Request.Cookies["ToolsTVExpand"];
" (cookie="" !="null" &&="" cookie.value="" int="" curridx="0;
" foreach="" (treenode="" mainnode="" in="" treeview1.nodes)
="" cookie.value,="" curridx);
="" }
="" catch="" (exception="" e)
="" just="" keep="" going
="" }
}
protected="" setnodestates(treenode="" node,="" string="" stateinfo,="" curridx)
{
="" (curridx="">= stateInfo.Length)
throw new Exception("State info shorter than list of nodes.");
Char state = stateInfo[currIdx];`enter code here`
if (state == 'e')
{
node.Expand();
}
currIdx++;
if (node.ChildNodes != null && node.ChildNodes.Count != 0)
{
foreach (TreeNode childNode in node.ChildNodes)
{
currIdx = setNodeStates(childNode, stateInfo, currIdx);
}
}

return currIdx;
}
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900