Сортировка дочерних узлов древовидной структуры после заполнения древовидной структуры в c # winforms - PullRequest
3 голосов
/ 11 апреля 2011

У меня проблемы с сортировкой дочерних узлов дерева в моей программе winforms.Мое древовидное представление заполняется некоторыми XML-файлами, и оно использует внутренний текст внутри XML-файлов в качестве свойства Text узлов (поэтому я думаю, что не могу отсортировать их перед добавлением их в древовидное представление или, если это возможно, поскольку XML-файлыбольшой по размеру я не хочу тратить впустую процесс).Заполненное древовидное представление в моей программе выглядит следующим образом:

enter image description here

Как вы можете догадаться, я хочу, чтобы дочерние узлы сортировались как (я не хочу, чтобы HBM \ D10 приходил после HBM \ D1)скорее я хочу:

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

Я уже пробовал treeView1.Sort (), а также добавлял beginUpdate и endUpdate, но у меня ничего не вышло: (

Я использую .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;
        } 
}

Ответы [ 4 ]

9 голосов
/ 11 апреля 2011

Вам необходимо создать собственный компаратор и присвоить его свойству 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 голосов
/ 12 апреля 2011

Я написал несколько пользовательских компараторов, чтобы сделать создание нужного вам компаратора здесь несколько проще: MultiComparer и ProjectionComparer.Вместе вы можете создать компаратор для сортировки того, что вам нужно, на лету без необходимости создавать класс вручную.То, что я здесь предоставляю, на самом деле не то, как у меня написаны классы, я для краткости обрезал много кода (хотя оставил несколько помощников, чтобы их было проще использовать).

Для созданиякомпаратор:

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);
    }
}
2 голосов
/ 11 апреля 2011

Вы используете алфавитную сортировку, поэтому D10 идет после D1.
Вы должны попытаться отсортировать отбрасывание символа "D" и преобразовать остаток строки в число.

0 голосов
/ 28 марта 2019

Ниже приводится решение, которое я использовал в своем текущем проекте.

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();              
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...