Запросить TreeNodeCollection
У меня есть элемент управления treeview на пользовательском интерфейсе формы Windows, и он имеет несколько узлов (с несколькими дочерними узлами).
Я хочу запросить коллекцию узлов, чтобы, скажем,
1. выберите те, чье имя начинается с "x"
2. выберите те, у которых нет данных в поле Node.Tag.
Может кто-нибудь, пожалуйста, предложите мне способ сделать это. Linq сделает его простым и аккуратным, но я не нашел ничего особенного в Linq для запроса TreeNodeCollection.
Спасибо,
Ответы
Ответ 1
Поскольку TreeNodeCollection
pre-date.NET 2.0, это не общий набор, поэтому он не реализует IEnumerable<T>
, который является "основным" типом для хорошего качества LINQ.
Однако вы можете просто вызвать .Cast<TreeNode>()
на TreeNodeCollection
, и вы получите IEnumerable<TreeNode>
, после чего вы сможете сделать все LINKy добро.
(этот подход работает для любой такой коллекции, которая реализует IEnumerable
, но не IEnumerable<T>
)
Ответ 2
Вы можете попробовать что-то подобное с помощью оператора Fixpoint, разрешающего рекурсивные lambdas
// Fix point operator
public static Func<T, T> Fix<T>(Func<Func<T, T>, Func<T, T>> f)
{
return t => f(Fix<T>(f))(t);
}
затем
// your treeView
var tv = new TreeView();
// Your filter Func
Func<TreeNode, bool> filterStartWithXorNoData =
node => node.Text.StartsWith("x") || string.IsNullOrEmpty(node.Text);
// Your recursive lambda
var filteredNodes = Fix<IEnumerable<TreeNode>>(
f =>
nodeList =>
nodeList.SelectMany(node => f(node.ChildNodes.Cast<TreeNode>()))
.Union(nodeList.Where(filterStartWithXorNoData)))
(tv.Nodes.Cast<TreeNode>());
Ответ 3
Я пробовал что-то подобное недавно и боролся с подходом LINQ из-за коллекции вложенных узлов под каждым родителем.
Я решил свою проблему с помощью рекурсивной функции, которая искала все узлы. Разумно элегантный.
VB:
Private Function FindNode(name As String, root As TreeNode) As TreeNode
For Each n As TreeNode In root.Nodes
If n.Name = name Then
'Found, get out
Return n
Else
'Recursively call FindNode to search this node children
Dim soughtNode = FindNode(name, n)
If soughtNode IsNot Nothing Then
Return soughtNode
End If
End If
Next
Return Nothing
End Function