如果我有一个TreeView(myTreeview),我怎样才能获得所选节点的所有父节点(父节点,父节点的父节点等)的列表?
答案 0 :(得分:7)
我建议你创建一组自己的树帮助器,例如,下一个是你的问题所在:
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
}
使用示例(在您的上下文中):
IList<TreeNode> ancestorList = TreeHelpers.GetAncestors(node, x => x.Parent).ToList();
为什么这比使用list&lt;&gt; .Add()更好? - 因为我们可以使用惰性LINQ函数,例如.FirstOrDefault(x =&gt; ...)
P.S。要将“当前”项目包含在可枚举的结果中,请使用TItem curItem = item
,而不是TItem curItem = getParentFunc(item)
答案 1 :(得分:3)
如果您想要实际的对象,请递归使用TreeNode.Parent属性,直到到达根目录。类似的东西:
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);
}
}
答案 2 :(得分:0)
亚历山大·马夫林斯基(Alexander Mavrinsky)的回答确实很有用,但是我的方法有很多变化。我的代码不仅在方法中,而且在调用站点中(通过指定他的泛型)更短,更清晰。
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;
}
}
例如:var firstCheckedAncestor = treeNode.GetAncestors().First(x => x.Checked);
或者,如果您确实需要每个父节点:var allAncestors = treeNode.GetAncestors().ToList();
但是,如果您打算使用相同的逻辑包含多个类,则这里是通用方法和每个类的几个扩展(因此您可以在每个调用方上保留更简单的API):
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);
答案 3 :(得分:-2)
我认为你需要一个节点数组
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);
}
}