2009-04-28 9 views
7

Ceci est un System.Windows.Forms.TreeView, pas un WPF ou un TreeView Web.Chargement différé de TreeView dans .NET

Je dois manquer quelque chose, car je ne peux pas croire que ce soit si difficile.

J'ai un TreeView sur mon formulaire. Le chargement de toutes les données pour peupler TreeView est très lent, donc je veux charger seulement les nœuds de niveau supérieur et remplir les enfants au fur et à mesure que l'utilisateur développe des nœuds. Le problème est que si un nœud n'a pas d'enfants, il n'affiche pas le signe + à côté du nœud, ce qui signifie qu'il ne peut pas être étendu, ce qui signifie que je ne peux pas capturer un événement Expanding pour charger les enfants . Il y a quelques années, lorsque j'utilisais PowerBuilder, vous définissiez une propriété HasChildren (ou similaire) sur true pour «mentir» au contrôle et le forcer à afficher le + et vous pouviez alors capturer l'événement Expanding. Je n'ai pas été capable de comprendre comment forcer un + à apparaître sur un nœud lorsqu'il n'y a pas de nœuds enfants. J'ai essayé une approche où j'ajoute un nœud fictif à chaque nœud puis en vérifiant si le nœud fictif est présent et l'enlève puis charge les enfants, mais pour diverses raisons qui ne valent pas la peine d'entrer ici cette solution n'est pas viable dans ma situation. J'ai recherché sur google pour différentes combinaisons de C#, treeview, retardé, différé, charge, force, expansion, et quelques autres termes qui m'échappent maintenant sans chance.

P.S. J'ai trouvé le projet TreeViewAdv sur SourceForge, mais je préfère ne pas introduire un nouveau composant dans notre environnement si je peux l'éviter.

+1

J'ai toujours utilisé la méthode du noeud factice; ça marche plutôt bien. Pouvez-vous nous en dire plus sur les raisons pour lesquelles cela ne fonctionnera pas pour vous? – Charlie

Répondre

4

Charger les 2 premiers niveaux au démarrage et la charge 2 niveaux vers le bas quand un nœud agrandi.

0

Une solution possible est de rester une longueur d'avance sur la TreeView:

private void Form1_Load(object sender, EventArgs e) 
{ 
    // initialise the tree here 
    var nodeSomething = treeView1.Nodes.Add("Something"); 
    nodeSomething.Nodes.Add("Something below something"); 

    treeView1.AfterExpand += AfterExpand; 
} 

private void AfterExpand(object sender, TreeViewEventArgs e) 
{ 
    foreach (TreeNode node in e.Node.Nodes) 
    { 
     // skip if we have already loaded data for this node 
     if (node.Tag != null) 
      continue; 
     node.Tag = new object(); 
     node.Nodes.AddRange(GetDataForThisNode(node)); 
    } 
} 
0

J'ai aussi demandé comment obtenir le + d'apparaître à côté de nœuds sans enfants, mais je ne trouve une bonne façon. Ma solution était de gérer l'événement MouseDoubleClick comme ceci:

Private Sub tvwMain_MouseDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles tvwMain.MouseDoubleClick 
    Dim oNode As TreeNode 

    oNode = tvwMain.GetNodeAt(e.X, e.Y) 

    If oNode IsNot Nothing Then 
     If oNode.Nodes.Count = 0 Then 
      'add children here 
     End If 
    End If 
End Sub 
2

Je suis d'accord avec Chris, j'ai dû faire varier chose. Chargez les noeuds supérieurs, puis capturez l'événement click, vérifiez que le clic est sur un noeud sélectionné, puis remplissez le noeud, puis développez-le.

Si vous avez besoin du plus, chargez les noeuds supérieurs et déposez-y un noeud factice. Assurez-vous de capturer l'événement click ou expand, effacez les nœuds, puis repeuplez-le.

+2

Je seconde l'idée du noeud factice. J'utilise cela moi-même et en définissant la propriété Tag à une valeur spécifique pour différencier les nœuds factices "Chargement ..." des autres. Dans BeforeExpand, je vérifie l'existence du noeud factice et remplace le contenu. Cela fonctionne bien pour moi. –

0

Avez-vous essayé d'inclure vos ajouts de noeuds dans les appels BeginUpdate() et EndUpdate()? Cela désactive toute peinture et, en tant que tel, vous permet d'ajouter un grand nombre de nœuds à TreeView sans délais significatifs.

MSDN: TreeView.BeginUpdate Method

+0

Je pense que l'OP signifiait que le chargement des données lui-même (à partir de DB, par exemple) était lent, ne pas ajouter les nœuds d'arbre, donc ils veulent charger les données à la demande (quand l'utilisateur étend chaque nœud d'arbre). – Lucas

+0

Lucas commentaire est correct. Le TreeView lui-même remplit assez rapidement, il obtient les données qui sont lentes. –

0

Vous pouvez avoir plus de chance en utilisant TreeViewAdv (sur sourceforge).