Archive for » April, 2009 «

Friday, April 03rd, 2009 | Author: admin

I have spent the last day trying to find a solution to what turns out to be a very common problem with the ASP.NET treeview control. Basically, I am pulling my data out of SQL and binding it to my treeview to use as navigation through a series of categories. My problem was that when I click a category (i’m redirecting to another page based on the category selected) the treeview loses all state and loads a fresh. Oh, my treeview control is in a user control btw, not in a master page.

The solution I came up with (couldn’t find a solution on the web that would work for me, i looked at the recursion method among many others, but for whatever reason it wouldn’t work. Maybe because the control is a user control and not directly within a master page??)  is rather a simple one, but it works! I’m sure there maybe more efficient and better ways of doing it, but like I said, this one works for me!

So this is what I do…
When a node is clicked I get the valuepath of the node via the SelectedNodeChanged event. I store this value in a session variable. When the resultant page loads I then use the OnPreRender method which is, and I quote;

"The PreRender event is raised just before the page is about to render its
contents. This is the last chance to modify a page output before it is sent
to the browser".

In this method I check to see if the session for the valuepath has any data. If it does I check to see if it has a separator. If there is that means we are more than one level deep into our treeview else if not, we are at the root level. If we are more than one level deep I throw the value into an array. I then basically loop through the array writing out the TreeView1.Findnode method as I go. So we are left with something like this;

TreeView1.FindNode("6").Expand();
TreeView1.FindNode("6/11").Expand();
TreeView1.FindNode("6/11/15").Expand();

That’s basically it. The code is below.

ASP.NET

<asp:TreeView ID="TreeView1" NodeWrap="true" ExpandDepth="0" runat="server"     OnTreeNodePopulate="TreeView1_TreeNodePopulate"
    PathSeparator="/" ImageSet="MSDN" CssClass="categoryMenu" OnDataBound="TreeView1_DataBound"
    OnSelectedNodeChanged="TreeView1_SelectedNodeChanged" ShowCheckBoxes="None"     SelectedNodeStyle-CssClass="categorySelected">
                <ParentNodeStyle Font-Bold="False" CssClass="navigationLink" />
                <HoverNodeStyle Font-Underline="True" ForeColor="" />
                <NodeStyle NodeSpacing="0px" VerticalPadding="0px" /></asp:TreeView>

 

 

C#

protected override void OnPreRender(EventArgs e)
    {
        if (Session["SelectedNodeValuePath"] != null)
        {
            //the selected node value is something like 6/11
            string nodeValuePath = Session["SelectedNodeValuePath"].ToString();

            //get the position of the first /
            int firstSeparator = nodeValuePath.IndexOf("/");

            if (nodeValuePath.IndexOf("/") > 0)
            {
                //define the character that separates
                char[] separator = { '/' };

                //split the string
                string[] array = nodeValuePath.Split(separator);

                StringBuilder path = new StringBuilder();
                int noArrayElements = array.Length;

                // if you select the third node down in a tree, the array will write out the following
                // TreeView1.FindNode("6").Expand();
                // TreeView1.FindNode("6/11").Expand();
                // TreeView1.FindNode("6/11/15").Expand();

                for (int i = 1; i < array.Length; i++)
                {
                    // if there is only one element in my array there is then only 1 node to expand.
                    if (noArrayElements == 1)
                    {
                        path.Append(array[i - 1]);
                        TreeView1.FindNode(path.ToString()).Expand();
                    }
                    // if there is more than one element i need to add the separator to the node path and then expand the node
                    if (noArrayElements > 1)
                    {
                        if (i == 1)
                        {
                            // don't prefix searator if first node
                            path.Append(array[i - 1]);
                            TreeView1.FindNode(path.ToString()).Expand();

                        }
                        else
                        {
                            // prefix separator for subsequent nodes
                            path.Append("/");
                            path.Append(array[i - 1]);
                            TreeView1.FindNode(path.ToString()).Expand();
                        }
                    }
                }

            }
            TreeView1.FindNode(Session["SelectedNodeValuePath"].ToString()).Select();

        }
    }

protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
    {
        //Get the value of the selected node
        int catID;
        catID = Convert.ToInt32(TreeView1.SelectedValue);
        string valuePath = TreeView1.SelectedNode.ValuePath;
        Session["selectedValue"] = catID;
        Session["SelectedNodeValuePath"] = valuePath;

        //Get the name of the selected category
        Category c = new Category(catID);
        string itemUrl = c.CatName;

        //pass the name through our clean URL class for URLrewriting
        itemUrl = CleanURLRewrite.cleanURL(itemUrl);

        //Check if we're rewriting urls and redirect accordingly
        if (System.Convert.ToBoolean((ConfigurationManager.AppSettings["EnableURLrewrite"])) == true)
        {
            Response.Redirect(ConfigurationManager.AppSettings["cartDirectory"].ToString() + "cat/" + catID + "/" + itemUrl + ".aspx", false);
        }
        else
        {
            Response.Redirect(ConfigurationManager.AppSettings["cartDirectory"].ToString() + "Items.aspx?category=" + catID.ToString(), false);
        }
    }

Category: ASP.NET, C#  | Leave a Comment