Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Sometimes treeview node won't collapse? 1

Status
Not open for further replies.

xpblueScreenOfDeath

Programmer
Sep 1, 2004
87
I created a lazy loading treeview. The tree only has 2 levels. I will allows load the first level. The second is loaded only if the user expands it. To make the plus appear for nodes that contains chidrens, I add one node with a empty string under each first level nodes. The only code that deals with expanding and collapsing a node is in the MouseDown event. Sometimes the node won't collapse but it would clear the child nodes and add one blank text node. If someone can tell me what I am doing wrong it would be great. Thanks.

Code:
        private void phoneTree_MouseDown(object sender, MouseEventArgs e)
        {
            System.Windows.Forms.TreeView tv = (System.Windows.Forms.TreeView)sender;
            System.Windows.Forms.TreeNode n = tv.GetNodeAt(e.X, e.Y);
            System.Windows.Forms.TreeNode childNode;
            System.Data.DataTable dt;
            System.Data.DataRow dRow;
            string[] values;
            int i;

            if (n != null && n.Level == 0)
            {
                n.Nodes.Clear();

                values = n.Tag.ToString().Split('_');

                if (int.Parse(values[1]) > 0)//node has sublevels
                {
                    if (!n.IsExpanded)
                    {
                        dt = fill in data table;

                        for (i = 0; i < dt.Rows.Count; i++)
                        {
                            dRow = dt.Rows[i];

                            childNode = new System.Windows.Forms.TreeNode();
                            childNode.Tag = string.Format("{0}_0", dRow["ID"]);//ID_hasChildren
                            childNode.Text = dRow["Desc"].ToString();

                            n.Nodes.Add(childNode);
                        }
                    }
                    else
                    {
                        n.Nodes.Clear();

                        childNode = new System.Windows.Forms.TreeNode();
                        n.Nodes.Add(childNode);
                    }
                }
            }
        }
 
What you describe as a bug is exactly what you coded it to do:

"...but it would clear the child nodes and add one blank text node..."

Code:
                    {
                        n.Nodes.Clear();

                        childNode = new System.Windows.Forms.TreeNode();
                        n.Nodes.Add(childNode);
                    }

In pseudo-code, your code says when a node has children and the node is not expanded then clear all children and add a blank one.

So everytime you try to collapse a node that has 'sublevels' this code will be executed. You should *first* check wether or not the node is expanded. If it is, then collapse it. If it's not, then do other checks like wether or not children must be added to it.

Regards, Ruffnekk
---
Is it true that cannibals don't eat clowns because they taste funny?
 
I'm assuming you are doing this because perhaps you have so many nodes to fill you do not want the performance hit when filling all of them at once?

I had a similar problem once.

I suggest that you fill all first child nodes with the data they are supposed to get and capture the "BeforeExpand" event to fill the rest of the data when expanded. (alternatively you could use a blank first child node as you are doing)

Once you have filled the data the first time, you can leave it. No need to delete it really. There is no performance benefit AFAIK in deleting it.

This would save you all the trouble your are encountering, unless of course your reasons are far different than what I am assuming

Then you can just ignore me :)
 
CrashDome:
Yeah, that is exactly what I am trying to do. I am clearing the nodes to save on the memory consumption. I tried using the event BeforeExpand before, but I couldn't figure out how to get the node that trigger the BeforeExpand event. The node that cause the expand is not the same as the selected node. If you could tell me that it would be a great help. Also, you mention that one way to do it is to fill in the first level without a blank first child node. But how you make it so that it shows that the node is expandable with the plus? Thanks.

Ruffnekk:
Well, isn't that what I wanted. If it is expanded, then I should clear the nodes and a one node to save on memory consumption. You said, "You should *first* check wether or not the node is expanded," but isn't that exactly what I did by the if not expanded else. Maybe, an example code by you will clearify your point.
 
Thanks CrashDome. I figure out how to get the node that cause the event expanding/collapsing event. So now I am using the BeforeExpand(load child nodes) and BeforeCollapse(unload child nodes). The TreeViewCancelEventArgs contains the node that trigger the event. Something about the name of the event cause me to think that it is not in there. But thanks.
 
My program that I did this in was for a ticket view for something like support tickets but for graphic arts... anyways, my database contained the ticket number table and a table for the postings (many postings per ticket relationship)

I would fill my dataset with the ticket numbers and use one child node for the subject of the ticket. These were in the same datarow so it was easy for me. I would fill the other child nodes with information about the originating post (Name of person, phone number, etc..) so after the expansion, I would query my database for the postings and fill the rest of the child nodes with data from the first posting.

Code:
TICKET#1
  |-- Ticket Subject
  |-- John Smith
  |-- Phone# 555-5555

So it isn't difficult, it's just how your data is structured and what you use for that first node.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top