2010-07-06 6 views
0

J'ai une table "Catégorie". Il s'agit simplement d'une table d'utilisateurs, où chacun est identifié avec un UserId unique et a un ParentId correspondant (pointant vers l'ID utilisateur de leur boss). S'il s'agit d'un utilisateur de niveau supérieur, l'ID Parent est défini sur 0. Quelqu'un peut-il m'aider à trouver la meilleure façon de remplir cette liste dans une arborescence?comment peupler treeview?

+0

Le Web ou celui des formulaires? –

Répondre

1

Si vous voulez dire WinForms TreeView je ferais quelque chose comme ça (vérification d'erreur sauté):

private void FillTreeView(object sender, EventArgs e) 
{ 
    // create fake datatable 
    DataTable dt = new DataTable(); 
    dt.Columns.Add("UserId",typeof(int)); 
    dt.Columns.Add("Name",typeof(string)); 
    dt.Columns.Add("ParentId", typeof(int)); 


    dt.Rows.Add(new object[] { 3, "Level_1_A", 2 }); 
    dt.Rows.Add(new object[] { 4, "Level_1_B", 2 }); 
    dt.Rows.Add(new object[] { 2, "Level_0_A", 0 }); 
    dt.Rows.Add(new object[] { 5, "Level_2_A", 3 }); 
    dt.Rows.Add(new object[] { 6, "Level_2_B", 3 }); 
    dt.Rows.Add(new object[] { 7, "Level_0_B", 0 }); 
    dt.Rows.Add(new object[] { 8, "Level_1_C", 7 }); 

    // call recursive function 
    AddCurrentChild(0, dt, treeView1.Nodes); 
} 

private static void AddCurrentChild(int parentId, DataTable dt, TreeNodeCollection nodes) 
{ 
    var rows = dt.Select("ParentId = " + parentId); 
    foreach (var row in rows) 
    { 
     var userId = (int) row["UserId"]; 
     var name = row["Name"] as string; 

     var node = nodes.Add(userId.ToString(), name.ToString()); 
     node.Tag = row; // if you need to keep a row reference on the node 
     AddCurrentChild(userId, dt, node.Nodes); 
    } 
} 
0

Je suppose que vous savez comment lire les données de base de données, donc je sauter cette partie.

Une version abstraite - vous pouvez lire les employés de n'importe quelle source.

Certaines entités d'aide (vous pouvez le faire sans les ofc - il est juste plus facile/plus agréable à utiliser cette façon):

/// <summary>The employee structure with explicit conversion to a TreeNode (you may also use implicit conversion, but i prefer explicit).</summary> 
public struct Employee 
{ 
    public int Id; 
    public string Name; 
    public int BossId; 

    public static explicit operator TreeNode(Employee e) { return new TreeNode(e.Name); } 
} 

public static class EmployeesExtension 
{ 
    /// <summary>More abstract and readable way to add an employee.</summary> 
    public static void Add(this Dictionary<int, List<Employee>> employees, int id, string name, int bossId) 
    { 
     if (!employees.ContainsKey(bossId)) employees[bossId] = new List<Employee>(); 

     employees[bossId].Add(new Employee() { Id = id, Name = name, BossId = bossId }); 
    } 
} 

La méthode utilisée pour remplir un TreeView:

public static void PopulateTreeView(Dictionary<int, List<Employee>> employees, int bossId, TreeNodeCollection nodes) 
{ 
    if (!employees.ContainsKey(bossId)) return; 

    foreach (Employee e in employees[bossId]) 
    { 
     TreeNode tn = (TreeNode)e; 
     nodes.Add(tn); 
     PopulateTreeView(employees, e.Id, tn.Nodes); 
    } 
} 

Comment l'utiliser dans votre code:

Dictionary<int, List<Employee>> employees = new Dictionary<int, List<Employee>>(); 

/* Here you will do the actual reading from DB */ 
//    id,  name,  bossId 
employees.Add(666, "The Master  ", 0); 
employees.Add(123, "The Underling 1", 666); 
employees.Add(879, "The Underling 2", 666); 
employees.Add(001, "The Slave 1 ", 123); 

this.treeView1.BeginUpdate(); 
PopulateTreeView(employees, 0, this.treeView1.Nodes); 
this.treeView1.EndUpdate(); 

Usin g les méthodes BeginUpdate/EndUpdate élimineront le "clignotement" de votre interface graphique.