首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在TreeView中对特定节点进行排序?

在TreeView中对特定节点进行排序?
EN

Stack Overflow用户
提问于 2022-08-02 15:27:36
回答 2查看 111关注 0票数 1

我想知道是否有任何方法对TreeView的特定节点进行排序(A)。

我要订购的节点是节点"Node1 \ z“

要像这样显示它:

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-08-03 09:26:20

一旦调用了TreeView.Sort方法,就可以通过隐藏Sorted属性的设置器实际应用排序的Sorted。使用默认排序器(升序字母排序)对所有节点进行排序的控件。任何之后以不同方式对节点进行排序的尝试都会失败。您将注意到,当删除、排序和重新插入特定节点的子节点时,不会发生任何事情,因为一旦插入这些子节点,默认的排序器将干扰并恢复不同的排序。同样,所有提到的都是在任何其他排序例程之前调用.Sort方法时。

若要重写此行为,需要为TreeView.TreeViewNodeSorter属性提供自定义节点排序器。一个允许您按升序或降序排序节点的树或子节点的示例。

代码语言:javascript
运行
复制
public class TreeNodeComparer : IComparer
{
    public TreeNodeComparer(SortOrder sortOrder = SortOrder.Ascending) : base()
    {
        SortOrder = sortOrder;
    }

    public int Compare(object x, object y)
    {
        var xn = x as TreeNode;
        var yn = y as TreeNode;

        switch (SortOrder)
        {
            case SortOrder.Descending:
                return string.Compare(xn.Text, yn.Text) * -1;
            case SortOrder.Ascending:
                return string.Compare(xn.Text, yn.Text);
            default:
                return 1;
        }
    }

    public SortOrder SortOrder { get; set; } = SortOrder.Ascending;
}

注意这里的return 1;,以防SortOrder.None必须恢复,对特定节点的子节点进行排序。

TreeViewTreeNode类型的几个扩展方法。

代码语言:javascript
运行
复制
public static class TreeViewExtensions
{
    public static void Sort(this TreeView self, SortOrder order = SortOrder.Ascending)
    {
        self.TreeViewNodeSorter = new TreeNodeComparer(order);
        self.Sort();
    }

    public static void Sort(this TreeNode self, SortOrder order = SortOrder.Ascending)
    {
        List<TreeNode> tmp;
        TreeView tv = self.TreeView;

        if (order == SortOrder.Descending)
            tmp = self.Nodes.Cast<TreeNode>().OrderByDescending(n => n.Text).ToList();
        else
            tmp = self.Nodes.Cast<TreeNode>().OrderBy(n => n.Text).ToList();

        var sorter = tv.TreeViewNodeSorter as TreeNodeComparer ?? new TreeNodeComparer();
        sorter.SortOrder = SortOrder.None;

        tv.TreeViewNodeSorter = sorter;
        tv.BeginUpdate();
        self.Nodes.Clear();
        self.Nodes.AddRange(tmp.ToArray());
        tv.EndUpdate();
    }
}

您可以按以下方式调用它们:

代码语言:javascript
运行
复制
// To sort the whole thing...
YourTreeView.Sort(SortOrder.Descending);

// Or the children of the selected node for example...
YourTreeView.SelectedNode.Sort(SortOrder.Ascending);

票数 0
EN

Stack Overflow用户

发布于 2022-08-03 02:57:42

您的问题是如何将alpha排序(A)应用于TreeView.中特定的单个节点。

有很多方法可以做到这一点,这些评论提到了一些好的方法。下面是一种解决方案,它使用树层次结构中的完全限定路径有效地定位目标节点。如果找到,则对其子级应用个性化排序方法(在运行时指定)。但是,首先,它必须确保TreeView通过将其Sorted属性设置为false来允许这种重新排序。这种方法的一个优点是避免为整个TreeView调用TreeView方法,因为这会增加不必要的复杂性层。

找到目标节点

给定TreeView的一条规则,即到任何节点(例如,@"Node1\z")的完全限定路径是唯一的,则可以通过为返回指定节点的TreeView (如果没有找到null )创建一个扩展来非常有效地获得目标。

代码语言:javascript
运行
复制
public static TreeNode Find(this TreeView treeView, string path)
{
    var parse = path.Split('\\');
    var nodes = treeView.Nodes;
    TreeNode node = null;
    foreach (var text in parse)
    {
        node = nodes.Cast<TreeNode>().FirstOrDefault(node => node.Text == text);
        if (node == null) break;
        nodes = node.Nodes;
    }
    return node;
}

排序目标节点的子节点

TreeNode的这个扩展根据作为参数传入的比较器Func对它的子类进行排序。

代码语言:javascript
运行
复制
public static void Sort(
    this TreeNode node,
    Func<TreeNode, TreeNode, int> sorter)
{
    // Make sure the TreeView will allow reordering
    if (node.TreeView != null)
    {
        node.TreeView.Sorted = false;
    }
    // Copy the nodes to a list
    var list = node.Nodes.Cast<TreeNode>().ToList();
    // Sort the list however the `Sorter` says to.
    list.Sort((a, b) => sorter(a, b));
    // Clear the 'old' order
    node.Nodes.Clear();
    // Install the 'new' order
    foreach (var sorted in list)
    {
        node.Nodes.Add(sorted);
    }
}

完全方法对TreeView.的特定节点进行排序(A)

因此,要回答的问题,有什么方法可以从any 中对TreeView的特定节点进行排序,假设我们通过为TreeView做一个扩展来制造这样的方法。对于path参数,指定整个层次结构路径,如@"Node1"@"Node1\z"

代码语言:javascript
运行
复制
public static bool SortIfNodeFound(
    this TreeView treeView, 
    string path, 
    Func<TreeNode, TreeNode, int> sorter)
{
    var node = treeView.Find(path);
    node?.Sort(sorter);
    return node != null;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73210073

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档