2012-04-13 12 views
10

Ich habe ein Treeview-Steuerelement auf einer Windows-Formular-Benutzeroberfläche und es hat ein paar Knoten (mit mehreren Kind-Knoten). Ich möchte die Nodes-Sammlung abfragen, zum Beispiel 1. Wählen Sie diejenigen, deren Name mit 'x' beginnen
2. Wählen Sie diejenigen, die keine Daten in Node.Tag Feld haben.Frage eine TreeNodeCollection

Kann mir bitte jemand einen Weg vorschlagen, dies zu tun. Linq würde es einfach und ordentlich machen, aber ich habe bei Linq nicht viel gefunden, um TreeNodeCollection abzufragen.

Danke,

+1

mit einem Fixpoint Bediener ermöglicht rekursive lambdas so etwas wie dies versuchen, Was ist die Tiefe Ihrer Treeview-Knoten? Wenn die untergeordneten Knoten selbst Knoten haben, benötigen Sie eine rekursive Abfrage. –

+0

Für jetzt kann ich sagen, Tiefe ist nur 1. – ViV

+1

Dieser Link könnte helfen .... [1]: http://stackoverflow.com/questions/1815497/enumerating-collections-that-are-not- inherently-ienumerable/1815600 # 1815600 –

Antwort

32

Da TreeNodeCollection pre-dates .NET 2.0, ist es nicht eine generische Sammlung, so dass es nicht IEnumerable<T>, die der 'Master' Typ für LINQ Güte ist nicht implementiert.

Allerdings können Sie rufen Sie einfach .Cast<TreeNode>() auf einem TreeNodeCollection, und Sie ein IEnumerable<TreeNode> bekommen, die Sie können dann alle LINQy Güte tun.

(dieser Ansatz funktioniert für eine solche Sammlung, die IEnumerable aber nicht IEnumerable<T> implementiert)

+0

Danke. Scheint, als würde es tun. Aber ich habe ein anderes Grundproblem. Ich habe folgendes versucht: 'IEnumerable childNodes = treeView2.Nodes.Cast (); var x = childNodes.Where (node ​​=> node.Tag == null); ' Dies funktioniert nicht wirklich, da childNodes nicht wirklich alle untergeordneten Knoten enthält. Grundsätzlich versuche ich dies zu tun: Ich habe eine Baumansicht mit n Knoten und jedem Knoten mit y Kindknoten. Ich möchte diesen ganzen Baum anhand einiger Kriterien herausfiltern. Wie gehe ich vor? Können Sie plz vorschlagen .. – ViV

+2

Wenn Sie den gesamten Baum durchsuchen möchten, scheint eine rekursive Methode die natürliche Wahl. Dies ist wahrscheinlich schon auf SO gekommen - eine schnelle Suche hat mich gefunden [http://stackoverflow.com/questions/177277/how-to-get-a-list-of-all-child-nodes-in- a-treeview-in-net), das in VB.NET ist, aber leicht übersetzbar sein sollte; Es wird noch viel mehr geben. – AakashM

2

Ich habe vor kurzem etwas Ähnliches versucht und kämpfte mit dem Ansatz LINQ aufgrund der verschachtelten Sammlung Knoten unter jedem Elternteil.

Ich löste mein Problem mit einer rekursiven Funktion, die alle Knoten durchforstete. Ziemlich elegant.

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

Können Sie bitte die Idee dahinter teilen. – ViV

3

Sie können

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

dann

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