Dove erro? Treeview e listview

martedì 07 ottobre 2008 - 12.12

riminese77 Profilo | Junior Member

Salve a tutti. Seguendo questo bell'esempio scritto da me....e si vede, mi succede una cosa diciamo strana. Quando clicco sul pulsante più acanto al C:\ la Tree mi dice che ho selezionato A: . Mentre se premo su C:\ allora la risposta nella msgbox è giusta C:\ e mi inserisce tutte le directori. Ma ovviamente le inserisce sotto alla radice primaria... come posso farle inserire sulla mia radice? Praticamente se clicco sul più mi prende sempre 0 di indice ecc...
La mia idea era quella di creare una serie di directori a destra che si aprivano e visualizzavano sempre e solo directory. Nella Listview solo i file.
La parte della list non l'ho ancora implementata, ma qui dove erro?

Private Sub FDir_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Dim Sdrivers() As String = Directory.GetLogicalDrives
Dim SDriver As String
Dim NewNodo As New TreeNode()
Dim i As Int16
For Each SDriver In Sdrivers
NewNodo = TreeView1.Nodes.Add(SDriver)
NewNodo.Text = (SDriver)
TreeView1.Nodes(i).Text = SDriver.ToString
NewNodo.Nodes.Add("Dummy")
i += 1
Next
End Sub

Private Sub TreeView1_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect
Dim N As TreeNode = CType(sender, Windows.Forms.TreeView).SelectedNode
Dim S As String = N.Text
If S.Length = 1 Then S = S.Insert(0, "0")
' S = N.Parent.Parent.Text & ":" & S
MessageBox.Show("You have selected: " & S)
Dim Onode As TreeNode = CType(e.Node, TreeNode)
MsgBox(TreeView1.SelectedNode.Text)
' If Onode.Nodes(0).Text = "Dummy" Then
'Onode.Nodes(0).Remove()
' End If

' Qui prende il nome del nodo Esempio C:\
Dim Sdrivers() As String = Directory.GetDirectories(e.Node.Text)

Dim SDriver As String
Dim NewNodo As New TreeNode()

For Each SDriver In Sdrivers
NewNodo = TreeView1.Nodes.Add(SDriver)
NewNodo.Nodes.Add("Dummy")
Next
End Sub

aiedail92 Profilo | Expert

Ciao

L'errore sta nel fatto che inserisci gli elementi alla TreeView come nodi di base anzichè come nodi di nodi. Inoltre ti consiglio di spostare il codice per aggiungere le sottocartelle nell'evento AfterExpand, invece che nell'AfterSelect. Ad esempio il codice potrebbe essere questo:


Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Luca

riminese77 Profilo | Junior Member

Ciao e grazie della risposta, vrei piacere di continuare qui l'avanzamento del programma che come già detto, deve fare un elenco directory sulla destra (eventuali icone come da sistema operativo) e l'elenco file (doc, pdf) sulla destra. Ora quello che mi hai dato funziona egragiamente, ho fatto qualche modifica e mi piacerebbe continuare con te la discussione.
Una volta schiacciato sul driver funziona e mi appaiono le subdir, poi quando schiaccio su una di essa, mi compare come prima casella un linea vuota e poi le giuste subdir.
Infine nella listview ho selezionato i file giusti, ma non riesco a visualizzare le icone corrispondenti esempio per word, pdf... ecc.

Reinserisco il codice, con l'aggiunta di un bottone.

Dim elencoFiles As String()
Dim i As Int16
Private Sub Form3_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim dummy As New TreeNode()
dummy.Tag = "dummy"
'Crea i nodi base della TreeView
Dim drivers As String() = Directory.GetLogicalDrives()
'Aggiunge ogni percorso base
Dim Cartelle As String
For Each Cartelle In drivers
Dim added As TreeNode = TreeView1.Nodes.Add(Cartelle)
added.Tag = Cartelle
added.Nodes.Add(dummy.Clone())
Next

End Sub
Private Sub TreeView1_AfterExpand(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterExpand
Try
TreeView1.BeginUpdate()
Dim dummy As New TreeNode()
'ottiene le sottodirectory del nodo
Dim dirs As String() = Directory.GetDirectories(e.Node.Tag)
Dim Sottocartelle As String

'Se il nodo non è popolato o vi è stato precedentemente un errore...
If e.Node.Nodes.Count = 1 AndAlso _
(e.Node.Nodes(0).Tag = "dummy" OrElse e.Node.Nodes(0).Tag = "errore") Then

'Rimuove il nodo dummy (o quello dell'errore)
e.Node.Nodes.RemoveAt(0)
'Cicla fra le sottodirectory
For Each Sottocartelle In dirs
'Aggiunge il nodo
Dim added As TreeNode = e.Node.Nodes.Add(Path.GetFileName(Sottocartelle))
added.Tag = Sottocartelle
'Aggiuge il nodo dummy
added.Nodes.Add(dummy.Clone)
Next
Else

'Cicla fra le sottodirectory

For Each Sottocartelle In dirs
MsgBox(dummy.Index)
'Aggiunge il nodo
Dim added As TreeNode = e.Node.Nodes.Add(Path.GetFileName(Sottocartelle))
added.Tag = Sottocartelle
'Aggiuge il nodo dummy
added.Nodes.Add(dummy.Clone)
Next

End If

TreeView1.EndUpdate()
Catch ex As Exception
'Rimuove il nodo dummy (o quello dell'errore)
e.Node.Nodes.RemoveAt(0)
e.Node.Nodes.Add(ex.Message).Tag = "errore"
TreeView1.EndUpdate()
End Try

End Sub

Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect

End Sub
Sub Vadoconfile(ByVal DammiDir As String)
Try
' Leggo il file
Dim myDir As DirectoryInfo = New DirectoryInfo(DammiDir)
' elencoFiles = Directory.GetFiles("C:\temp\", "*.doc") '"*.doc,*.pdf,*.jpg")
'MsgBox(TreeView1.SelectedNode.FullPath)
Dim UnFile As FileInfo
Dim li As ListViewItem

For Each UnFile In myDir.GetFiles
li = ListView1.Items.Add(UnFile.Name)
li.ImageIndex = i
'imageListLarge.Images.Add(Bitmap.FromFile(aFile.FullName))
i = i + 1
Next
Catch

End Try
End Sub


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Vadoconfile(TreeView1.SelectedNode.FullPath)
End Sub

Magari vediamo insieme qualche modifica e miglioramenti....molti miglioramenti

aiedail92 Profilo | Expert

Ciao

Ho riveduto e corretto il codice, commentato, rimosso parti inutili e aggiunto la visualizzazione delle icone:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Luca

riminese77 Profilo | Junior Member

Ciao, ho inserito il tuo esempio su VB.net express e funziona OTTIMAMENTE grazie dell'aiuto. Ora provo a sostituire TreeView con Dirlistbox componente non di defualt, ma semplice.

Peccato che io uso Vb 2002 ovviamente non potevi sapere ed io non l'ho detto, nonostante gli oggetti siano uguali non funziona!
Ora provo a modificare alcuni errori che ti riporto. Eventualmente lo reinserisco così chi ha la sfortuna di avere un Vb.net "mancato" lo sfrutta al 100%.

'Estrae l'icona associata al file Dim icn As Icon = Icon.ExtractAssociatedIcon(file.FullName)
Ho inserito imports drawing, ma ExtractAssociatedIcon non è un membro del drawing che ho.

'Aggiunge l'icona all'elenco dell'ImageList li.ImageList.Images.Add(ext, icn)
Impossibile convertire il tipo String,icon in drawing

li.ImageKey = ext
Imagekey non è un membro del listview

Da quello che posso capire è un problema del framework che non ha le librerie adatte, ma sfortunatamente a me serve la divulgazione del programma. Se non è possibile svilupperò il tutto nell' Express e poi per distribuirlo (solo a due persone visto che è vietata la distribuzione sotto questa versione),prendo un installer gratuito. Se tutto funge compro l'upgrade a Vb 2008 tanto senza non si fa nulla.


aiedail92 Profilo | Expert

Ciao

Ho provato a modificare il codice, adesso la funzione ExtractAssociatedIcon viene chiamata direttamente come API di Windows, quindi non hai il problema del framework. Vedi se le modifiche che ho fatto correggono anche gli altri due errori:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Luca

riminese77 Profilo | Junior Member

Mi dice Dim loadedIcons As New Dictionary(Of String, IntPtr) che Dicrionary non è un membro definito.

aiedail92 Profilo | Expert

Prova a vedere se hai importato correttamente il namespace System.Collections.Generics (non so se esiste già dal Framework usato dal VB 2002)

In alternativa modifica quella riga in

Dim loadedIcons As New System.Collections.Hashtable()

Luca

riminese77 Profilo | Junior Member

No, dalla versione che ho io non c'è collection.generic, infatti avevo visto su internet quale imports inserire ma sfortunatamente.... ora ho inserito la tua riga e non da errore, ma mancano solo questi due :

li.ImageList.Images.Add(ext, img) dove mi dice (impossibile convertire string in ico, imposs. convertire image in color)
sostituita con
li.ImageList.Images.Add(img)

li.ImageIndex = li.ImageList.Images.IndexOfKey(ext) indexofkey non è un membro.
sostiuita con
li.ImageIndex = ext

ma non mi funziona, io ho la versione 2002 del solo Vb.net ora ho fatto domanda se è possibile dare il semplice upgrade a VS standar .Almeno sono al pari, mancando librerie e altre funzioni, già che non son capace... mi imbroglio di più :) che ne pensi? il costo se è possibile si aggira sui 199 €. Che dovrei rifarmi in breve.

aiedail92 Profilo | Expert

Ciao

Penso che se hai la diponibilità passare almeno alla versione 2005 sia buona cosa; il Framework 2.0 è decisamente migliore e più completo rispetto all'1.0\1.1. Come dire, il gioco vale la candela

Luca
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5