Šlo by to udělat například tak, že pro každou TreeNode, která ještě nebyla načtena vytvoříte jednu dceřinnou TreeNode, aby se zobrazil znak "+" a při otevření té TreeNode smažete tuto zástupnou TreeNode (může mít například Text "načítání", pokud získávání dat může nějakou dobu trvat - síť) a doplníte nové získáné větve. Vytvořil jsem ukázkový kód, který to demonstruje. Metoda MagicallyGetChildren je určena k nahrazení Vámi dodaným mechanismem pro získávání položek, momentálně dělá jen to, že generuje tolik větví, kolik je udáno ve vlastnosti Tag větve, pro kterou děti generujeme. Každé z těchto dětí má následně přiřazeno do Tagu náhodné číslo v intervalu <0,3>, které umožní další větvení stromu, pokud tomu bude pseudonáhoda přát.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Počáteční vytvoření zkušebních dat (5 větví)
TreeView1.Nodes.AddRange(MagicallyGetChildren(New TreeNode() With {.Tag = 5}))
End Sub
Dim random As New Random()
Private Sub TreeView1_AfterExpand(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterExpand
' Pokud je Tag prázdný, položky už byli získány, neděláme nic
If Not e.Node.Tag Is Nothing Then
' Dočasně vypneme překreslování stromu
TreeView1.BeginUpdate()
' Schováme "Loading" větev
e.Node.Nodes.Clear()
' Přidáme získané položky
e.Node.Nodes.AddRange(MagicallyGetChildren(e.Node))
' Obnovíme vykreslování stromu
TreeView1.EndUpdate()
' Nastavíme Tag na Nothing, aby se tato funkce už nemohla znovu vyvolat pro stejnou větev
e.Node.Tag = Nothing
End If
End Sub
''' <summary>
''' Retrieves data from external source and generates child tree nodes based on that data.
''' </summary>
''' <param name="node">A node to generate data for.</param>
''' <returns>An array of child nodes for given node.</returns>
''' <remarks>
''' Make sure children was not already retrieved or duplicate results will appear.
''' This is a dummy function that returns random nodes, replace it with something useful.
''' </remarks>
Private Function MagicallyGetChildren(node As TreeNode) As IEnumerable(Of TreeNode)
' TODO: Implement data retrieval and return real nodes
Dim children As New List(Of TreeNode)
For index = 0 To DirectCast(node.Tag, Integer) - 1
Dim generatedChildrenCount = random.Next(0, 3)
children.Add(New TreeNode(String.Format("Will generate {0} children.", generatedChildrenCount), New TreeNode() {New TreeNode("Loading…")}) With {.Tag = generatedChildrenCount})
Next
Return children.ToArray()
End Function
PS: Dejte si pozor na to, jak budete implementovat ExpandAll(), pokud to Váš software umožňuje. Možná to bude chtít zapojit další vlákno, pokud pracujete se sítí, nebo s databází, které bude zodpovědné za získávání dat, dosazování je do TreeView a podobně. Já si teď namátkou zkusil ExpandAll() na tomto a dostal jsem se do tisíců větví (důsledek náhodného generování), takže jestli tuto funkcionalitu plánujete zprovoznit také, určitě se zamyslete nad vhodným mechanismem pro plánování stahování dat.
|