How to get all parents (up to root) nodes for selected in TreeView control?

梦想的初衷 提交于 2019-12-08 19:48:01

问题


If I have a TreeView (myTreeview),how can I obtain a list of all parent nodes (parent, parents of parents ect.) of selected node?


回答1:


I'd recomended you to create a set of your own tree helpers, for example, next one is for your problem:

    public static class TreeHelpers
    {
        public static IEnumerable<TItem> GetAncestors<TItem>(TItem item, Func<TItem, TItem> getParentFunc)
        {
            if (getParentFunc == null)
            {
                throw new ArgumentNullException("getParentFunc");
            }
            if (ReferenceEquals(item, null)) yield break;
            for (TItem curItem = getParentFunc(item); !ReferenceEquals(curItem, null); curItem = getParentFunc(curItem))
            {
                yield return curItem;
            }
        }

        //TODO: Add other methods, for example for 'prefix' children recurence enumeration
    }

And example of usage (in your context):

        IList<TreeNode> ancestorList = TreeHelpers.GetAncestors(node, x => x.Parent).ToList();

Why is this better than using list<>.Add()? - because we can use lazy LINQ functions, such as .FirstOrDefault(x => ...)

P.S. to include 'current' item into result enumerable, use TItem curItem = item, instead of TItem curItem = getParentFunc(item)




回答2:


If you want the actual objects, use the TreeNode.Parent property recursively until you reach the root. Something like:

private void GetPathToRoot(TreeNode node, List<TreeNode> path)
{
    if(node == null) return; // previous node was the root.
    else
    {
        path.add(node);
        GetPathToRoot(node.Parent, path);
    }
}



回答3:


Alexander Mavrinsky's answer is really useful, but my approach has many changes. My code is shorter and clearer not only in the method, but also in the call sites (by specifying his generics).

public static class TreeExtensions
{
    public static IEnumerable<TreeNode> GetAncestors(this TreeNode node)
    {
        if (node == null)
            yield break;
        while ((node = node.Parent) != null)
            yield return node;
    }
}

For instance: var firstCheckedAncestor = treeNode.GetAncestors().First(x => x.Checked);

Or if you really need every parent node: var allAncestors = treeNode.GetAncestors().ToList();


But if you plan to have more than one class using the same logic, here is the generic method and a couple of extensions for each class (so you can keep the simpler API on each caller):

public static IEnumerable<T> GetAncestors<T>(T item, Func<T, T> getParent)
{
    if (item == null)
        yield break;
    while ((item = getParent(item)) != null)
        yield return item;
}
public static IEnumerable<TreeNode> GetAncestors(this TreeNode node) => GetAncestors(node, x => x.Parent);
public static IEnumerable<Control> GetAncestors(this Control control) => GetAncestors(control, x => x.Parent);



回答4:


I Think you need to take an Array of Nodes

List<TreeNode> resultNodes = new List<TreeNode>()
private void GetNodesToRoot(TreeNode node)
{
    if(node == null) return; // previous node was the root.
    else
    {
        resultNodes.add(node);
        GetNodesToRoot(node.Parent);
    }
}


来源:https://stackoverflow.com/questions/8120746/how-to-get-all-parents-up-to-root-nodes-for-selected-in-treeview-control

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!