按类型和字母顺序 A->Z 对树视图节点进行排序

Posted

技术标签:

【中文标题】按类型和字母顺序 A->Z 对树视图节点进行排序【英文标题】:Sorting tree view nodes by type and alphabetically A->Z 【发布时间】:2021-08-12 07:21:29 【问题描述】:

我正在开发一个使用树视图的应用程序。树视图具有三种类型的节点:

根节点:无法排序,其标签包含字符串 “根”来识别它们 文件夹:可以排序的,想法是总是在顶部的其他节点之前,并按 A->Z 的升序排序。这些具有“文件夹”标签。 其他:想法是那些在文件夹之前,并且按 A->Z 升序排序

这是这个树形视图的外观:

这个想法是对根节点(声音、音频数据)内的所有子节点进行排序,并始终将文件夹放在节点之前。

我一直在尝试使用此代码,但不起作用:

// 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;
    

代码经过优化也很有趣,因为这个树形视图可以轻松包含超过 500 个节点。

谢谢!

【问题讨论】:

当您说“无法对根节点进行排序”时,您是指以根节点为父节点的子节点吗?您的屏幕截图是否包含任何“根”节点? 是的,我的意思是像“音频数据”和“声音”这样的节点。 【参考方案1】:

根节点没有父节点,它们的Level 属性返回0,因此您不需要使用它们的Tag 属性来识别它们。您只需要在排序器中识别Folder 节点即可对它们进行排序并将它们保持在其他节点之上。然后最后对其余部分进行排序。

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);
    

【讨论】:

【参考方案2】:

逻辑可以简化为先按 Taģ 排序,然后按 Text。因此,如果标签不同,则需要比较的是标签。如果标签相同,则比较文本。

假设标签类型是这样的:

public enum TagType

    Root,
    Folder,
    Other

那么下面的逻辑应该起作用:

// 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);
      

【讨论】:

以上是关于按类型和字母顺序 A->Z 对树视图节点进行排序的主要内容,如果未能解决你的问题,请参考以下文章

在桌子视图的按字母顺序的部分在迅速

在laravel中按字母顺序排序集合

根据字符串属性按字母顺序对对象数组进行排序

php判断$1 or $j and $z 顺序

如何创建按分类术语对节点进行分组的视图?

XML 反序列化忽略不按字母顺序排列的属性