jms2505
jms2505

Reputation: 76

Sorting tree view nodes by type and alphabetically A->Z

I'm working on an application that uses a tree view. The tree view has three type of nodes:

Here's how this tree view looks:

enter image description here

The idea is to sort all child nodes inside the root nodes (Sounds, Audio Data), and having always the folders before the nodes.

I've been trying with this code but does not work:

// Create a node sorter that implements the IComparer interface.
public class NodeSorter : IComparer
{
    public int Compare(object x, object y)
    {
        int resultComparing;
        TreeNode tx = x as TreeNode;
        TreeNode ty = y as TreeNode;

        if (tx.Tag.ToString().Equals("Root") || ty.Tag.ToString().Equals("Root"))
        {
            resultComparing = 2;
        }
        else if (tx.Tag.ToString().Equals("Folder") || ty.Tag.ToString().Equals("Folder"))
        {
            resultComparing = string.Compare(tx.Tag.ToString(), ty.Tag.ToString(), true);
        }
        else
        {
            resultComparing = string.Compare(tx.Text, ty.Text, true);
        }

        return resultComparing;
    }
}

It would also be interesting that the code are very optimized because this tree view can contain easily more than 500 nodes.

Thanks!

Upvotes: 0

Views: 1478

Answers (2)

bwakabats
bwakabats

Reputation: 703

The logic can be simplified to sort by Taģ then by Text. So if the Tags are different it is the Tags that need comparing. If the Tags are the same then compare Text.

Assuming the Tag types are in this order:

public enum TagType
{
    Root,
    Folder,
    Other
}

Then the following logic should work:

// Create a node sorter that implements the IComparer interface.
public class NodeSorter : IComparer
{
    public int Compare(object x, object y)
    {
        TreeNode tx = x as TreeNode;
        TreeNode ty = y as TreeNode;

        if (tx.Tag != ty.Tag)
            return tx.Tag.CompareTo(ty.Tag);

        return string.Compare(tx.Text, ty.Text, true);
    }  
}

Upvotes: 1

dr.null
dr.null

Reputation: 4695

The root nodes have no parents and their Level properties return 0 so you don't need to use their Tag properties to identify them. You just need to identify the Folder nodes in the sorter to sort and keep them on top of the other nodes. Then lastly sort the rest.

public class NodeSorter : IComparer
{
    public int Compare(object x, object y)
    {
        var nx = x as TreeNode;
        var ny = y as TreeNode;

        // Keep the order of the root nodes...
        if (nx.Level == 0 || ny.Level == 0) return 1;

        // If x is Folder...
        if (nx.Tag is string sx && sx == "Folder")                
        {
            // And y is Folder...
            if (ny.Tag is string sy && sy == "Folder")
                // Then, sort them...
                return string.Compare(nx.Text, ny.Text, true);

            // Otherwise, x precedes y...
            return -1;
        }
        // If y is Folder...
        else if (ny.Tag is string sy && sy == "Folder")
            // Then, x follows y...
            return 1;

        // Sort the other nodes...
        return string.Compare(nx.Text, ny.Text, true);
    }
}

Upvotes: 1

Related Questions