问题
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