TreeView mit mehreren Ebenen füllen



  • Guten Morgen!

    Ich möchte zu unseren Artikel Stücklisten erstellen.
    Die Daten dafür sind in einer Tabelle.
    p_ident = Hauptartikel
    c_ident = Artikel in der Stückliste

    treeArtikel.Nodes.Clear();
    
                    conn.Open();
                    MySqlCommand cmd = new MySqlCommand("SELECT DISTINCT ident, ben1 FROM data WHERE ident = '" + cbxArtikelIdent.SelectedItem.ToString() + "' ORDER BY ident;", conn);
                    dr = cmd.ExecuteReader();
    
                    string[,] ident = new string[10000, 2];
                    int count = 0;
    
                    while (dr.Read())
                    {
                        if (dr.IsDBNull(0) == false && dr.IsDBNull(1) == false)
                        {
    
                            ident[count, 0] = dr.GetString(0);
                            ident[count++, 1] = dr.GetString(0) + "    " + dr.GetString(1);
                        }
                    }
                    dr.Close();
                    conn.Close();
    
                    for (int loop = 0; loop < count; loop++)
                    {
                        TreeNode root = new TreeNode();
                        root.Text = ident[loop, 1];
    
                        conn.Open();
                        MySqlCommand cmd2 = new MySqlCommand("SELECT DISTINCT a.posnr, a.c_ident, b.ben1, a.count FROM struct a, data b WHERE a.c_ident = b.ident AND a.p_ident = '" + ident[loop, 0] + "' ORDER BY a.posnr;", conn);
                        dr2 = cmd2.ExecuteReader();
    
                        while (dr2.Read())
                        {
                            if (dr2.IsDBNull(0) == false && dr2.IsDBNull(1) == false && dr2.IsDBNull(2) == false && dr2.IsDBNull(3) == false)
                            {
                                TreeNode child = new TreeNode();
    
                                child.Text = dr2.GetString(0) + "    " + dr2.GetString(1) + "    " + dr2.GetString(2) + "    " + dr2.GetString(3);
                                root.Nodes.Add(child);
                            }
                        }
                        treeArtikel.Nodes.Add(root);
                        dr2.Close();
                        conn.Close();
    

    Das klappt soweit auch prima!

    Nun mein Problem/Frage:
    Ein Artikel in der Stückliste kann ja auch mal ein Parent (p_ident) sein.
    Was muss ich machen, damit ich weitere Ebenen füllen kann? 😕

    Ich hoffe hier auf Hilfe, da ich langem Probieren leider zu keiner Lösung gekommen bin.



  • Ich bin noch zu müde für die Frage weil ich sie nicht verstanden habe.
    Wenn es darum geht ein Child weitere CHilds anzufügen:

    Child.Nodes.Add();
    


  • Du solltest die Liste Recursive eintragen.
    Ist dann alles einfacher und übersichtlicher.
    Der Funktion übergibst du das Parent und in dem werden die Child eingefügt.
    Sollte das Child wieder Childs haben dann Recursive aufrufen.



  • Leider hab ich keine Ahnung, wie ich den rekursiv durchlaufen kann.
    Ich werde mal googeln, vielleicht werde ich fündig!



  • Erstmal würde ich die Daten in eine Klasse packen das ist übersichtlicher als dein mehrdimensionales Array.

    public class p_ident
    {
     public string ident,benl;
    }
    
    public class c_ident:p_ident
    {
     public string pos_nr;
     public string count;
    }
    

    Dann brauchst eine rekursive Funktion die ein Nodecollection und ein p_ident annimmt.

    void rek_CreateNode(TreeNodeCollection nodes,p_ident ident)
    {
      TreeNode new_node = new TreeNode();
      c_ident child_product = ident as c_ident;
      if(child_product != null)
      {
        new_node.Text = child_product.pos_nr+" "+ child_product.ident +" "+child_product.ben_l +" "+child_product.count;
      }
      else
      {
        new_node.Text = ident.ident +" " + ident.ben_l;
      }
      nodes.Add(new_node);
      conn.Open();
      List<c_ident> child_products = new List<c_ident>();
      MySqlCommand cmd2 = new MySqlCommand("SELECT DISTINCT a.posnr, a.c_ident, b.ben1, a.count FROM struct a, data b WHERE a.c_ident = b.ident AND a.p_ident = '" + ident.ident + "' ORDER BY a.posnr;", conn);
     dr2 = cmd2.ExecuteReader();
     while (dr2.Read())
     {
      if (dr2.IsDBNull(0) == false && dr2.IsDBNull(1) == false && dr2.IsDBNull(2) == false && dr2.IsDBNull(3) == false)
      {
        c_ident cp = new c_ident();
        cp.posnr = dr.GetString(0);
        cp.ident = dr.GetString(1);
        cp.ben_l = dr.GetString(2);
        cp.count = dr.GetString(3);
        child_products.Add(cp);
      }
     }
     dr2.Close();
     conn.Close();
     foreach(c_indent c in child_products)
     {
      rek_CreateNode(new_node.Nodes,c);
     }
    }
    

    Und rufst sie so auf

    treeArtikel.Nodes.Clear();
    conn.Open();
    MySqlCommand cmd = new MySqlCommand("SELECT DISTINCT ident, ben1 FROM data WHERE ident = '" + cbxArtikelIdent.SelectedItem.ToString() + "' ORDER BY ident;", conn);
    dr = cmd.ExecuteReader();
    List<p_ident> parent_products = new List<p_ident>();
    while (dr.Read())
    {
     if (dr.IsDBNull(0) == false && dr.IsDBNull(1) == false)
     {
       p_ident new_product = new p_ident();
       new_product.ident = dr.GetString(0);
       new_product.ben_l = dr.GetString(1);
       parent_product.Add(new_product);
     }
    }
    dr.Close();
    conn.Close();
    foreach(p_ident p in parent_products)
    {
      rek_CreateNode(treeArtikel.Nodes,p);
    }
    


  • Vielen Dank, das sieht schon recht gut aus ...
    Nur gibt es doch noch ein Problem. Mir scheint es, als ob ich immer in einer Endlosschleife lande.

    System.StackOverflowException" ist in mscorlib.dll aufgetreten.

    An der Stelle

    MySqlCommand cmd = new MySqlCommand("SELECT DISTINCT a.posnr, a.c_ident, b.ben1, a.count FROM pwpartstruct a, pwdata b WHERE a.c_ident = b.ident AND a.p_ident = '" + ident.ident + "' ORDER BY a.posnr;", conn2);
               dr = cmd.ExecuteReader();
    

    Vielleicht hat jemand eine Idee, an was das liegen könnte?! Danke!



  • Du könntest ein Produkt haben das sein ParentProdukt oder ein ParentProdukt seines ParentProdukts als Child hat.Dann würde die Funktion immer wieder aufgerufen.



  • @Andorxor
    Habe zu Testzwecken ne neue Tabelle erzeugt und nur mit ein paar Einträgen gefüllt. Dann funktioniert es wunderbar! Vielen Dank für Deine Hilfe!!
    Muss nun mal schauen, was ich an der Tabelle (bzw. SQL String) ändern kann, damit das mit den Originaldaten auch klappt.
    Nochmals danke!


Anmelden zum Antworten