C# – Re-Sorting treeview Nodes[0] only after being populated

csortingtreeviewwinforms

I have the following tree:

Animals
 |
 |___Zebra
 |    |__Head
 |    |__Arms
 |    |__Legs
 |   
 |___Monkey
      |__Head
      |__Arms
      |__Legs

Each animal has an ID number stored in the Tag field and their name is in Name field of node.I want to press a button that says "Sort by ID" and have the "Zebra" above turn into "14" etc, and then resort numerically. However, I want the children to stay with the head, arms, legs order. When I use the following code, it works, but it also re-sorts the head arms legs into arms, head, legs. I've tried a NodeSorter, but I just didn't get any different results. I'm also very new to C# so I might have implemented it incorrectly. 🙂 I'm also using a custom node with a few extra fields to store data and boolean values. That's what the "JacksNode" refers to below.

Here's the code:

public static void sortByAnimalID(TreeView tv)
    {
        tv.BeginUpdate();
        foreach (TreeNode treeNode in tv.Nodes[0].Nodes)
        {
            if (((JacksNode)treeNode).IsAnimal)
            {
                treeNode.Text = Convert.ToString(treeNode.Tag);
                treeNode.Name = Convert.ToString(treeNode.Tag);
            }
        }
        tv.Sort();
        tv.EndUpdate();
    }

Any ideas on what I'm doing wrong? I've searched the web for two weeks and have been overwhelmed with all the treeview articles. However, none have been this specific.
Thanks guys/gals for any suggestions.

Best Answer

Use the TreeNode.Level property to figure out how to compare node properties. Like this:

    private void SortButton_Click(object sender, EventArgs e) {
        if (treeView1.TreeViewNodeSorter == null) {
            treeView1.TreeViewNodeSorter = new NodeSorter();
        }
    }
    private class NodeSorter : System.Collections.IComparer {
        public int Compare(object x, object y) {
            TreeNode node1 = (TreeNode)x;
            TreeNode node2 = (TreeNode)y;
            if (node1.Level == 1) {
                return Convert.ToInt32(node1.Tag).CompareTo(Convert.ToInt32(node2.Tag));
            }
            else {
                return node1.Index.CompareTo(node2.Index);
            }
        }
    }
Related Topic