在c#winforms中填充树视图后对树视图的子节点进行排序

问题描述 投票:3回答:4

我在winforms程序中排序树视图的子节点时遇到问题。我的树视图由一些XML文件填充,它使用xml文件中的内部文本作为节点的Text属性(所以我认为在将它们添加到树视图之前我无法对它们进行排序,或者如果可能的话,因为xml文件是大尺寸我不想浪费这个过程)。我程序中的填充树视图如下所示:

你可以猜到我希望子节点排序(我不希望HBM \ D10在HBM \ D1之后出现)而我想要:

    HBM\D1
    HBM\D2
    HBM\D3
etc...

我已经尝试过treeView1.Sort()并且还添加了beginUpdate和endUpdate,但我没有suceess :(

我正在使用.NET 4,任何提示将不胜感激

好吧我用托马斯的建议把它整理出来:

    class NodeSorter : IComparer
{
        public int Compare(object x, object y) 
        {         
            TreeNode tx = (TreeNode)x; 
            TreeNode ty = (TreeNode)y;

            if (tx.Text.Length < ty.Text.Length)
            {
                return -1;
            }

            if (tx.Text.Length > ty.Text.Length)
            {
                return 1;
            }

            return 0;
        } 
}
c# winforms sorting treeview
4个回答
9
投票

您需要创建自定义比较器并将其分配给TreeViewNodeSorter属性:

public class NodeSorter : System.Collections.IComparer
{
    public int Compare(object x, object y)
    {
        TreeNode tx = (TreeNode)x;
        TreeNode ty = (TreeNode)y;

        // Your sorting logic here... return -1 if tx < ty, 1 if tx > ty, 0 otherwise
        ...
    }
}


...

treeView.TreeViewNodeSorter = new NodeSorter();
treeView.Sort();

2
投票

你正在使用字母排序,所以D10在D1之后。 您应该尝试排序丢弃“D”字符并将其余字符串转换为数字。


2
投票

我写了一些自定义比较器来创建你需要的比较器,这里更容易做:MultiComparerProjectionComparer。您可以一起创建一个比较器,以便在不需要手动创建类的情况下对您需要的内容进行排序。我在这里提供的实际上并不是我如何编写类,为了简洁我修剪了很多代码(尽管让一些助手更容易使用)。

要创建比较器:

var comparer = OrderedComparer.Create(
    ProjectionComparer.Create((TreeNode tn) => tn.Text.Substring(0, 1)),
    ProjectionComparer.Create((TreeNode tn) => Convert.ToInt32(tn.Text.Substring(1)))
);
treeView.TreeViewNodeSorter = comparer;

和班级:

public static class OrderedComparer
{
    public static OrderedComparer<TSource> Create<TSource>(params IComparer<TSource>[] comparers)
    { return new OrderedComparer<TSource>(comparers); }
}
public static class ProjectionComparer
{
    public static ProjectionComparer<TSource, TKey> Create<TSource, TKey>(Func<TSource, TKey> keySelector)
    { return new ProjectionComparer<TSource, TKey>(keySelector); }
}
public sealed class OrderedComparer<TSource> : Comparer<TSource>
{
    public OrderedComparer(params IComparer<TSource>[] comparers)
    {
        this.comparers = comparers.ToArray();
    }
    private IComparer<TSource>[] comparers;

    public override int Compare(TSource x, TSource y)
    {
        var cmp = 0;
        foreach (var comparer in comparers)
            if ((cmp = comparer.Compare(x, y)) != 0)
                break;
        return cmp;
    }
}
public sealed class ProjectionComparer<TSource, TKey> : Comparer<TSource>
{
    public ProjectionComparer(Func<TSource, TKey> keySelector)
    {
        this.keySelector = keySelector;
        this.keyComparer = Comparer<TKey>.Default;
    }
    private Func<TSource, TKey> keySelector;
    private IComparer<TKey> keyComparer;

    public override int Compare(TSource x, TSource y)
    {
        var xKey = keySelector(x);
        var yKey = keySelector(y);
        return keyComparer.Compare(xKey, yKey);
    }
}

0
投票

以下是我在当前项目中使用的解决方案。

public class NodeSorter : IComparer
{
   public int Compare(object x, object y)
   {
      TreeNode tx = x as TreeNode;
      TreeNode ty = y as TreeNode;
      if (tx.Name== null || ty.Name== null)
         return 0;
      return (-1) * string.Compare(tx.Name.ToString(), ty.Name.ToString());
   }
} 

tvListofItems.TreeViewNodeSorter = new NodeSorter();
tvListofItems.Sort();              
© www.soinside.com 2019 - 2024. All rights reserved.