For a normal alphabetical sort simply call the built-in sort:
treeView1.Sort();
and you are good.
But sometimes this is not good enough. Then you need to write a custom sorter. This is really simple; all it needs to provide is an int
for the result of <
, ==
or >
, i.e. return -1
, 0
or 1
respectively. Often the built-in comparers will do after massaging the data a bit..
Here is an example of a custom sorter. This is a simple class implementing the IComparer
interface, which has just one method..
It prepares the two node texts for my custom comparison before calling the regular string Compare
method.
The preparation inserts a large number of zeroes to pad a trailing number to a constant length.
It is just an example but will sort e.g. the default names from the designer numerically/chronologically.
public class NodeSorter : System.Collections.IComparer
{
public NodeSorter() { }
public int Compare(object x, object y)
{
TreeNode tx = x as TreeNode;
TreeNode ty = y as TreeNode;
string s1 = tx.Text;
while (s1.Length > 0 && Char.IsDigit(s1.Last())) s1 = s1.TrimEnd(s1.Last());
s1 = s1 + tx.Text.Substring(s1.Length).PadLeft(12, '0');
string s2 = tx.Text;
while (s2.Length > 0 && Char.IsDigit(s2.Last())) s2 = s2.TrimEnd(s2.Last());
s2 = s2 + ty.Text.Substring(s2.Length).PadLeft(12, '0');
return string.Compare(s1, s2);
}
}
You call it by assigning it and then calling sort:
treeView1.TreeViewNodeSorter = new NodeSorter();
treeView1.Sort();
Result:



This is a slightly modified version of the MSDN TreeNodeSorter example. Besides the changed logic do note:
- The example is old and doesn't qualify the
IComparer
interface properly. With the advent of generics we usually have a using System.Collections.Generic;
clause and this will hide the non-generic IComparer
interface, leading to compiler errors, complaining about the missing type arguments.
Adding the qualification takes care of that..:
public class NodeSorter : System.Collections.IComparer