Il controllo TreeView
Il controllo TreeView visualizza informazioni all'interno di
una struttura ad albero. Ogni elemento e' detto nodo dell'albero. Ogni
nodo puo' contenere altri nodi. Il controllo si basa sulla collection Nodes,
i cui elementi appartengono al tipo TreeNode. Operativamente,
scegliamo un nodo esistente e vi inseriamo un TreeNode, dopo
averlo precedentemente creato. A ciascun elemento della TreeView possiamo
associare un'icona. Per introdurre le icone ci avvaliamo della proprieta': ImageList.
In questa lista, le immagini sono ordinate per indice. Quando vogliamo
assegnare un'immagine, lo facciamo impostando una delle due proprieta' ImageIndex,
SelectedImageIndex del nodo, con l'indice dell'immagine
voluta.
Presentiamo un esempio dove il TreeView e' impiegato per
realizzare un Folder Browser. Ogni nodo rappresenta una directory. Marchiamo
con un "+" quelle directory che ne contengono delle altre. Una ComboBox ci
permette di cambiare Drive, ma non gestiamo gli errori su un'eventuale
assenza di drive rimovibile.
Contolli utilizzati nel Form:
-
ComboBox - Name = ComboBox1
-
TreeView - Name = TreeView1
1) ExtractIconEx e' un'api di Windows che importiamo per
estrarre le icone che assoceremo ai nodi dell'albero. Images e'
la lista di immagini che estrarremo. ExtractFolderIcons e' la
procedura che estrae effettivamente le icone. Tali icone si trovano nella dll
di systema Shell32.
Imports System.IO
...
Public Declare Ansi Function ExtractIconEx Lib "Shell32.dll" _
(ByVal lpszFile As String, _
ByVal nIconIndex As Integer, ByVal phIconLarge As IntPtr(), _
ByVal phIconSmall As IntPtr(), ByVal nIcons As Integer) _
As Integer
Dim Images As ImageList
Private Sub ExtractFolderIcons()
Images = New ImageList()
Dim shell32_path As String = Environment.SystemDirectory
Dim SmallIcons(2) As IntPtr
Dim icn As Icon
Dim n As Integer
' 3 - icona "Cartella chiusa", 4 - icona "Cartella aperta"
n = ExtractIconEx(shell32_path & "\shell32.dll", 3, _
Nothing, SmallIcons, 2)
icn = Icon.FromHandle(SmallIcons(0))
Images.Images.Add(icn)
icn = Icon.FromHandle(SmallIcons(1))
Images.Images.Add(icn)
' 8 - icona drive
n = ExtractIconEx(shell32_path & "\shell32.dll", 8, _
Nothing, SmallIcons, 1)
icn = Icon.FromHandle(SmallIcons(0))
Images.Images.Add(icn)
End Sub
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
ExtractFolderIcons()
SetDrives()
End Sub
2) La seguente procedura carica la ComboBox con la lista di Drive disponibili.
Quindi sceglie il drive corrente e lo imposta come default. Infine popola
l'albero al primo livello, dovrebbe mostrare soltanto il drive.
Private Sub SetDrives()
Dim drives() As String = Directory.GetLogicalDrives
Dim i As Integer
ComboBox1.Items.Clear()
ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
For i = 0 To drives.Length - 1
ComboBox1.Items.Add(drives(i))
Next
i = ComboBox1.FindStringExact(Directory.GetDirectoryRoot( _
Directory.GetCurrentDirectory))
ComboBox1.SelectedIndex = i
RecreateTree(ComboBox1.Text)
End Sub
3) Cancella tutti i nodi con il metodo Clear sulla collection
Nodes. Aggiunge il nodo root con Add e chiama
AddChildren per aggiungere tutte le directory contenute nel nodo root. Notate
che, al nodo appena creato, assegnamo l'immagine il cui indice e' 2: (icona del
drive) ImageIndex, SelectedImageIndex.
Forniamo la lista di immagini attraverso la proprieta' ImageList.
Private Sub RecreateTree(ByVal drive As String)
TreeView1.Nodes.Clear()
TreeView1.ImageList = Images
Dim node As TreeNode = TreeView1.Nodes.Add(drive)
AddChildren(drive, node)
node.ImageIndex = 2
node.SelectedImageIndex = 2
End Sub
4) Estrae tutti le sottodirectory della directory fornita dal percorso sPath. E
le aggiunge al nodo n. Ogni nodo ha la sua collection Nodes alla
quale e' possibile aggiungere altri nodi con il metodo Add.
Private Sub AddChildren(ByVal sPath As String, ByRef n As TreeNode)
Dim files() As String
Try
files = Directory.GetDirectories(sPath)
Catch e As Exception
Return
End Try
Dim i As Integer
For i = 0 To files.Length - 1
n.Nodes.Add(Path.GetFileName(files(i)))
Next
End Sub
5) Questo evento scatta quando l'utente seleziona un nuovo drive nella
ComboBox. Ci limitiamo a ricreare l'albero in base al drive scelto.
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
RecreateTree(ComboBox1.Text)
End Sub
6) Questa routine e' fondamentale. Si aggancia all'evento BeforeExpand
del TreeView. L'evento e' generato prima che un nodo venga
espanso, dopo il click dell'utente. A ciascun nodo contenuto che andremo a
visualizzare, dobbiamo aggiungere i nodi che conterra', in modo che il
controllo possa visualizzare il "+" di espansione. Prima di aggiungere i nodi,
bisogna eliminare eventuali nodi presenti, per evitare di duplicarli
visititando piu' volte lo stesso nodo. La tecnica di aggiungere ad ogni
vistita, si rende necessaria per non dover creare tutto l'albero di un'intera
partizione!! Notate la proprieta' FullPath che ci da' l'intero
percorso che dalla radice porta al nodo interessato. Quando la directory viene
espansa, bisogna cambiare la sua icona in modo che mostri l'icona aperta: con
l'indice 1, impostiamo tale icona.
Private Sub TreeView1_BeforeExpand(ByVal sender As Object, _
ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) _
Handles TreeView1.BeforeExpand
Dim n As TreeNode
For Each n In e.Node.Nodes
n.Nodes.Clear()
AddChildren(n.FullPath, n)
Next
If Not e.Node.Parent Is Nothing Then
e.Node.ImageIndex = 1
e.Node.SelectedImageIndex = 1
End If
End Sub
7) Quest'evento e' generato quando un nodo viene chiuso. In tal caso dobbiamo
far disegnare l'icona di folder chiusa, il cui indice e' 0.
Private Sub TreeView1_AfterCollapse(ByVal sender As Object, _
ByVal e As System.Windows.Forms.TreeViewEventArgs) _
Handles TreeView1.AfterCollapse
If Not e.Node.Parent Is Nothing Then
e.Node.ImageIndex = 0
e.Node.SelectedImageIndex = 0
End If
End Sub
Ultimo aggiornamento 13/01/2004
|