2012-04-13 21 views
10

Tôi có quyền kiểm soát treeview trên giao diện người dùng biểu mẫu cửa sổ và có một vài nút (với nhiều nút con). Tôi muốn truy vấn bộ sưu tập nút để, ví dụ: 1. chọn những người có tên bắt đầu bằng 'x'
2. chọn những người không có bất kỳ dữ liệu nào trong trường Node.Tag.Truy vấn TreeNodeCollection

Ai đó có thể đề nghị tôi làm cách này. LINQ sẽ làm cho nó dễ dàng và gọn gàng, nhưng tôi không tìm thấy gì nhiều trên Linq để truy vấn TreeNodeCollection.

Cảm ơn,

+1

Độ sâu của các nút treeview của bạn là bao nhiêu? nếu các nút con có các nút, bạn cần một truy vấn đệ quy. –

+0

Hiện tại, tôi có thể nói chiều sâu chỉ là 1. – ViV

+1

Liên kết này có thể giúp ... [1]: http://stackoverflow.com/questions/1815497/enumerating-collections-that-are-not- vốn có thể là/ienumerable/1815600 # 1815600 –

Trả lời

32

TreeNodeCollection trước ngày .NET 2.0, nó không phải là một bộ sưu tập chung, vì vậy nó không thực hiện IEnumerable<T>, đó là 'thầy' kiểu cho LINQ tốt lành.

Tuy nhiên, bạn chỉ có thể gọi .Cast<TreeNode>() trên TreeNodeCollection, và bạn nhận được một IEnumerable<TreeNode>, mà bạn có thể sau đó làm tất cả những sự tốt lành LINQy tới.

(phương pháp này làm việc cho bất kỳ bộ sưu tập như vậy mà thực hiện IEnumerable nhưng không IEnumerable<T>)

+0

Cảm ơn. Có vẻ như sẽ làm. Nhưng tôi có một vấn đề cơ bản khác. Tôi đã thử những điều sau: 'IEnumerable childNodes = treeView2.Nodes.Cast (); var x = childNodes.Where (node ​​=> node.Tag == null); ' Điều này không thực sự hiệu quả vì ChildNodes không thực sự chứa các nút con 'ALL'. Về cơ bản, tôi đang cố gắng thực hiện việc này: Tôi có một khung nhìn tre với n nút và mỗi nút có nút con y. Tôi muốn lọc toàn bộ cây này trên một số tiêu chí. Làm thế nào để tôi đi về nó. Bạn có thể plz đề nghị .. – ViV

+2

Nếu bạn muốn tìm kiếm toàn bộ cây, một phương pháp đệ quy có vẻ là sự lựa chọn tự nhiên. Điều này có thể xuất hiện trên SO trước đó - một tìm kiếm nhanh chóng tìm thấy tôi [this] (http://stackoverflow.com/questions/177277/how-to-get-a-list-of-all-child-nodes-in- a-treeview-in-net) trong VB.NET nhưng phải dễ dàng dịch; sẽ có nhiều hơn nữa. – AakashM

2

Tôi đã thử một cái gì đó tương tự gần đây và phải vật lộn với các cách tiếp cận LINQ do bộ sưu tập các nút lồng bên dưới mỗi phụ huynh.

Tôi đã giải quyết được sự cố của mình bằng chức năng đệ quy tìm kiếm tất cả các nút. Hợp lý thanh lịch.

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

Bạn có thể chia sẻ ý tưởng đằng sau không. – ViV

3

Bạn có thể thử một cái gì đó như thế này với một nhà điều hành Fixpoint phép lambdas đệ quy

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

sau đó

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