如果我有一个TreeView控件 (myTreeview),那么如何获取所选节点的所有父节点列表(包括直接父节点和祖先节点)呢?
我建议您创建一组自己的树形辅助函数,例如,下面这个函数可以解决您的问题:
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<>.Add()更好?- 因为我们可以使用惰性LINQ函数,例如.FirstOrDefault(x => ...)
附注:要将“当前”项目包含在结果可枚举对象中,请使用TItem curItem = item
,而不是TItem curItem = getParentFunc(item)
如果你需要实际对象,请递归使用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);
}
}
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);
我认为你需要使用节点数组
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);
}
}