2012-04-13 13 views
10

Tengo un control treeview en una interfaz de usuario de Windows y tiene algunos nodos (con varios nodos secundarios). Quiero consultar la colección de nodos para, por ejemplo, 1. seleccionar los cuyo nombre empiece por 'x'
2. seleccione los que no tengan datos en el campo Node.Tag.Consultar una TreeNodeCollection

¿Puede alguien sugerirme una manera de hacer esto. Linq lo haría fácil y ordenado, pero no encontré mucho en Linq para consultar TreeNodeCollection.

Gracias,

+1

¿Cuál es la profundidad de tus nodos treeview? si los nodos secundarios tienen nodos, necesita una consulta recursiva. –

+0

Por ahora, puedo decir que la profundidad es solo 1. – ViV

+1

Este enlace podría ayudar .... [1]: http://stackoverflow.com/questions/1815497/enumerating-collections-that-are-not- inherentemente-ienumerable/1815600 # 1815600 –

Respuesta

32

Debido TreeNodeCollection anterior a .NET 2.0, no es una colección genérica, por lo que no implementa IEnumerable<T>, que es del tipo 'maestro' para LINQ bondad.

Sin embargo, sólo puede llamar a .Cast<TreeNode>() en un TreeNodeCollection, y se obtiene una IEnumerable<TreeNode>, que puede luego hacer todo el bien que LINQy.

(este enfoque funciona para cualquier colección que implementa IEnumerable pero no IEnumerable<T>)

+0

Gracias. Parece que va a hacer. Pero tengo otro problema básico. Intenté lo siguiente: 'IEnumerable childNodes = treeView2.Nodes.Cast (); var x = childNodes.Where (node ​​=> node.Tag == null); ' Esto realmente no funciona porque childNodes realmente no contiene 'TODOS' los nodos secundarios. Básicamente, estoy tratando de hacer esto: tengo una vista de árbol con n nodos y cada nodo tiene nodos secundarios. Quiero filtrar todo este árbol según algunos criterios. ¿Cómo lo hago? ¿Puede sugerir por favor ... – ViV

+2

Si desea buscar todo el árbol, un método recursivo parece ser la elección natural. Probablemente esto haya aparecido en SO antes: una búsqueda rápida me encontró [esto] (http://stackoverflow.com/questions/177277/how-to-get-a-list-of-all-child-nodes-in- a-treeview-in-net) que está en VB.NET pero debe ser fácilmente traducible; habrá muchos más – AakashM

2

he intentado algo similar recientemente y luchaban con el enfoque LINQ debido a la recogida de los nodos anidados debajo de cada padre.

Resolví mi problema con una función recursiva que buscaba en todos los nodos. Razonablemente elegante.

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's children 
      Dim soughtNode = FindNode(name, n) 
      If soughtNode IsNot Nothing Then 
       Return soughtNode 
      End If 
     End If 
    Next 

    Return Nothing 

End Function 
+0

¿Puedes compartir la idea? – ViV

3

Usted puede intentar algo como esto con un operador de Punto fijo permitiendo lambdas recursivas

// 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); 
} 

continuación

// 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>());