2012-05-30 12 views
5

Mam tabelę z 3 kolumnami, ID, Name i ParentID. Kolumna ID zawiera numer bieżący, który służy również jako klucz podstawowy. Identyfikator będzie również własnością węzła o nazwach o nazwie. Kolumna nazwy zawiera ciąg znaków, który będzie atrybutem treenode'a, podczas gdy ParentID jest kolumną zawierającą macierzysty identyfikator węzła.Jak dynamicznie wypełniać widok drzewa (C#)

To jest jak moja tabela wygląda następująco:

ID  Name ParentID 
====================== 
1  A  0 
2  A1  1 
3  B  0 
4  C  0 
5  A2  1 
6  B1  3 

Powyższa tabela pokazuje, że węzeł A jest węzeł nadrzędny dla węzła A1 i A2. ParentID równy "0" oznacza, że ​​rodzicem węzła jest węzeł główny (zakodowany na stałe). Np. Węzeł A, B i C są potomkami węzła głównego.

Sortuję wiersze według ParentID przed zapełnieniem widoku drzewa. I wypełnić widok drzewa przy użyciu tych dwóch metod (TreeNode node oto childNode które są umieszczane w drzewie):

private void SearchParent(TreeView tree, String parentID, TreeNode node) 
    { 
     // Post: call TraverseParent method to search parent 

     TreeNodeCollection collection = tree.Nodes; 

     // Search parent recursively 
     foreach (TreeNode n in collection) 
     { 
      TraverseParent(n, parentID, node); 
     } 
    } 

    private void TraverseParent(TreeNode potentialParent, String parentID, TreeNode node) 
    { 
     // Post: search for parent. When parent is found add child to parent 

     // am i the parent that you're looking for? 
     if (parentID.CompareTo(potentialParent.Name) == 0) 
     { 
      // found me! i'm your parent! 

      // add child to parent 
      potentialParent.Nodes.Add(node); 

      // update that the parent for child has been found 
      parentFound = true; 
     } 
     else 
     { 
      // i'm not your parent 

      // continue to look for parent recursively 
      foreach (TreeNode n in potentialParent.Nodes) 
      { 
       TraverseParent(n, parentID, node); 
      } 
     } 
    } 

Wszystko jest dobrze dopóki nie przeciągnij-i-upuść węzłów poprzez węzeł A dziecko węzła C i zatwierdzić zmiany w bazie danych.

Teraz moja tabela bazy danych wygląda następująco:

ID  Name ParentID 
====================== 
1  A  4 
2  A1  1 
3  B  0 
4  C  0 
5  A2  1 
6  B1  3 

Następnym razem uruchomić aplikację, to nie trafia do zapełniania węzła A1 i A2 do drzewa, bo nie mógł znaleźć swoich rodziców. To dlatego, kiedy posortować wiersze na podstawie parentId przed wypełniania TreeView, wiersze są klasyfikowane następująco:

ID  Name ParentID 
====================== 
3  B  0 
4  C  0 
2  A1  1 
5  A2  1 
6  B1  3 
1  A  4 

ten sposób moja aplikacja będzie starał się zapełnić A1 i A2 węzły w drzewie jeszcze przed węzłem A jest tworzony. Dlatego aplikacja nie może znaleźć elementu nadrzędnego dla węzła A1 i A2.

W związku z tym, czy ktoś może mi powiedzieć sposób naprawienia tego błędu lub czy istnieje lepszy sposób dynamicznie wypełnić widok drzewa?

Dzięki.

+1

Zobacz tutaj - http://stackoverflow.com/questions/361661/populate-treeview-from-database –

+0

Dziękuję za link! – ixora

Odpowiedz

14

Powinieneś użyć rekursji, aby ją wypełnić.

Obiecany przykład:

public partial class Form1 : Form 
    { 
     private class ItemInfo 
     { 
      public int ID; 
      public int ParentID; 
      public string Name; 
     } 

     public Form1() 
     { 
      InitializeComponent(); 
      FillTreeView(); 
     } 

     private void FillTreeView() 
     { 
      var items = new List<ItemInfo>() 
      { 
       new ItemInfo(){ID = 1, ParentID = 4, Name = "A"}, 
       new ItemInfo(){ID = 2, ParentID = 1, Name = "A1"}, 
       new ItemInfo(){ID = 3, ParentID = 0, Name = "B"}, 
       new ItemInfo(){ID = 4, ParentID = 0, Name = "C"}, 
       new ItemInfo(){ID = 5, ParentID = 1, Name = "A2"}, 
       new ItemInfo(){ID = 6, ParentID = 3, Name = "B1"}, 
      }; 

      FillNode(items, null); 
     } 

     private void FillNode(List<ItemInfo> items, TreeNode node) 
     { 
      var parentID = node != null 
       ? (int)node.Tag 
       : 0; 

      var nodesCollection = node != null 
       ? node.Nodes 
       : treeView1.Nodes; 

      foreach (var item in items.Where(i => i.ParentID == parentID)) 
      { 
       var newNode = nodesCollection.Add(item.Name, item.Name); 
       newNode.Tag = item.ID; 

       FillNode(items, newNode); 
      } 
     } 
    } 
+0

Awesome, gratulacje! – copa017

Powiązane problemy