adszone.org
venerdì 20 settembre 2024
"Il modo corretto di pensare il software"
home
consulenza  vb.net  contatti 
  Visual Basic .NET
  ListView
Domande

Il controllo ListView

Come indica il nome, il controllo ListView visualizza liste di oggetti. E' il classico controllo utilizzato dal File Browser di Windows. Sono disponibili quattro tipi di visualizzazione: icone grandi, icone piccole, lista e dettagli. Si cambia visualizzazione tramite la proprieta' View. Essa puo' assumere valori in base all'enumerazione View:

  • Details - Gli elementi sono disposti uno per riga. Ogni riga e' suddivisa in piu' colonne, la prima contiene l'elemento stesso, le altre, visualizzano i suoi attributi, detti Sub Items. Ogni colonna ha un'intestazione, Header. La prima colonna puo' contenere anche una piccola icona.
  • SmallIcon - Ogni elemento e' visualizzato con una piccola icona e del testo alla sua destra.
  • LargeIcon - Ogni elemento e' visualizzato con un'icona e del testo in basso.
  • List - Ogni elemento e' visualizzato con una piccola icona e del testo alla sua destra. Gli elementi sono organizzati in colonne senza intestazione.

La proprieta' Items e' la collection di elementi che il controllo conterra'. La proprieta' Columns e' la collection che contiene le instestazioni delle colonne (disponibili solo in Details). A ciascun elemento della ListView possiamo associare un'icona grande ed una piccola. Per introdurre le icone ci avvaliamo di due proprieta': SmallImageList, LargeImageList, esse sono oggetti di tipo ImageList . In queste liste, le immagini sono ordinate per indice. Quando vogliamo assegnare un'immagine, lo facciamo impostando la proprieta' ImageIndex del elemento, con l'indice dell'immagine voluta.

Vediamo l'impiego della ListView con un esempio. Ci proponiamo di realizzare un File Browser elementare. Un doppio click su un elemento che sia una directory, ci permette di entrare in tale directory. I doppi punti indicano la directory superiore.

Contolli utilizzati nel Form:

  • ListView - Name = Listview1
  • Button - Name = btnOrdina, Text = "Ordina"
  • RadioButton - Name = radioDetails, Text = "Dettagli"
  • RadioButton - Name = radioList, Text = "Lista"
  • RadioButton - Name = radioSmall, Text = "Icone piccole"
  • RadioButton - Name = radioLarge, Text = "Icone grandi"

Notate che abbiamo bisogno di importare l'api di Windows, ExtractIconEx, per estrarre delle icone che inseriremo come immagini per gli elementi della lista.

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 SmallImages As ImageList
    Dim LargeImages As ImageList
		
    Dim m_Dir As String

La seguente procedura estrae effettivamente un paio di immagini dal file di sistema Shell32.dll che contiene le immagini dell'icona "Folder". Alternativamente, avremmo dovuto disegnare la coppia di icone, grande e piccola, per conto nostro. La procedura ha lo scopo di estrarre le due icone ed inserirle nelle liste di immagini: SmallImages, LargeImages.

    Private Sub ExtractFolderIcons()
        SmallImages = New ImageList()
        LargeImages = New ImageList()
        Dim shell32_path As String = Environment.SystemDirectory
        Dim SmallIcons(0) As IntPtr
        Dim LargeIcons(0) As IntPtr
        Dim icns As Icon, icnl As Icon
        Dim n As Integer

        n = ExtractIconEx(shell32_path & "\shell32.dll", 3, _
                        LargeIcons, SmallIcons, 1)

        icns = Icon.FromHandle(SmallIcons(0))
        SmallImages.Images.Add(icns)

        icnl = Icon.FromHandle(LargeIcons(0))

        LargeImages.Images.Add(icnl)
        LargeImages.ImageSize = New Size(32, 32)
    End Sub

La procedura popola illustra l'impiego della ListView. Essa viene eseguita ad ogni cambio di directory, per aggiornare il contenuto della lista.

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As _ 
            System.EventArgs) Handles MyBase.Load
        ExtractFolderIcons()
        radioDetails.Checked = True
        m_Dir = Directory.GetCurrentDirectory()
        Popola()
    End Sub

    Private Sub Popola()
        Me.Text = m_Dir
        Directory.SetCurrentDirectory(m_Dir)

1) Clear() - Togliamo tutti gli elementi precedentemente inseriti. MultiSelect - Vogliamo poter selezionare un solo elemento alla volta. GridLines - Facciamo visualizzare una griglia. Sorting = SortOrder.None - Non vogliamo che la lista sia inizialmente ordinata. Assegnamo alle proprieta' SmallImageList e LargeImageList le liste precedentemente ottenute con ExtractFolderIcons.

        ' 1) Inizializza la lista
        ListView1.Items.Clear()
        ListView1.MultiSelect = False
        ListView1.GridLines = True
        ListView1.Sorting = SortOrder.None
        ListView1.SmallImageList = SmallImages
        ListView1.LargeImageList = LargeImages
        

2) Aggiungiamo un'intestazione per i dettagli. Utilizziamo il metodo Add sulla collection delle colonne. Questo crea nuove colonne dove noi specifichiamo, il testo, l'ampiezza e l'allineamento.

        ' 2) Aggiunge due colonne
        ListView1.Columns.Add("File", ListView1.Width / 2, _
            HorizontalAlignment.Left)
        ListView1.Columns.Add("Size", ListView1.Width / 2, _
            HorizontalAlignment.Left)

3) Otteniamo, in base alla directory selezionata, due array contenenti file e directory da inserire nella lista.

        ' 3) Reperisce file e directory della directory specificata
        Dim files() As String = Directory.GetFiles(m_Dir)
        Dim directories() As String = Directory.GetDirectories(m_Dir)
        Dim lvi As ListViewItem
        Dim fi As FileInfo
        Dim di As DirectoryInfo
        Dim i As Integer

Notate che abbiamo inserito l'aggiunta degli elementi tra i metodi BeginUpdate() e EndUpdate(). Questi fanno in modo che il controllo venga ridisegnato soltanto al termine degli aggiornamenti, cosi' da evitare antiestetici effetti di sfarfallamento.

        ListView1.BeginUpdate()

4) Se non ci troviamo sulla directory root, aggiungiamo anche i ".." per indicare la directory superiore. Un elemento si aggiunge nella collection Items con il metodo Add, fornendogli un oggetto di tipo ListViewItem, il cui costruttore richiede il testo da visualizzare e l'indice (0, in questo caso) dell'icona da associare.

        ' 4) Aggiunge la Directory Parent, se esiste
        If Directory.GetDirectoryRoot(m_Dir) <> m_Dir Then
            lvi = New ListViewItem("..", 0)
            ListView1.Items.Add(lvi)
        End If

5) Per ogni directory, inseriamo un elemento come visto nel punto 4) ed inoltre inseriamo il testo "directory" nella colonna attributo. Le colonne degli attributi vengono individuate dalla collection SubItems. Anche qui, creiamo l'elemento fornendogli l'indice dell'icona da associare.

        ' 5) Aggiunge tutte le directory
        For i = 0 To directories.Length - 1
            di = New DirectoryInfo(directories(i))
            lvi = New ListViewItem(Path.GetFileName(directories(i)), 0) ''
            lvi.SubItems.Add("Directory")
            ListView1.Items.Add(lvi)
        Next

6) Per ogni file, inseriamo un elemento come visto nel punto 4) ed inoltre inseriamo la dimensione del file nella colonna attributo. Le colonne degli attributi vengono individuate dalla collection SubItems. Non abbiamo preparato un'icona per file che non siano directory, quindi omettiamo di indicare un indice nel costruttore di ListViewItem.

        ' 6) Aggiunge tutti i file
        For i = 0 To files.Length - 1
            fi = New FileInfo(files(i))
            lvi = New ListViewItem(Path.GetFileName(files(i)))
            lvi.SubItems.Add(fi.Length)
            ListView1.Items.Add(lvi)
        Next

        ListView1.EndUpdate()
    End Sub

Ogni volta che facciamo un doppio click su una directory, vi accediamo. SelectedIndices e' l'insieme degli indici degli Item selezionati, Count ci dice quanti sono. In base alle nostre impostazioni, possono essere uno o nessuno. Se non abbiamo cliccato sopra nessun elemento possiamo uscire dalla Sub. SelectedItems e' l'insieme degli elementi selezionati. Item(0) ci da' l'elemento selezionato. Lo utilizziamo per controllare l'operazione da compiere. Nei due casi possibili impostiamo la nuova directory e poi ripopoliamo la lista.

    Private Sub ListView1_DoubleClick(ByVal sender As Object, _
            ByVal e As System.EventArgs) Handles ListView1.DoubleClick
        If ListView1.SelectedIndices.Count = 0 Then Exit Sub

        Dim sItem As String = ListView1.SelectedItems.Item(0).Text

        If sItem = ".." Then
            m_Dir = Directory.GetParent(m_Dir).FullName
            Popola()
            Exit Sub
        End If

        Dim fa As FileAttribute = File.GetAttributes(sItem)
        If fa = FileAttribute.Directory Then
            m_Dir = Path.Combine(m_Dir, sItem)
            Popola()
            Exit Sub
        End If
    End Sub

Impostando la proprieta' Sorting, determiniamo il tipo di ordinamento. Con il metodo Sort ordiniamo effettivamente.

    Private Sub Ordina_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles btnOrdina.Click
        ListView1.Sorting = SortOrder.Ascending
        ListView1.Sort()
    End Sub

Quattro pulsanti radio ci permettono di cambiare il tipo di vista con la proprieta' View.

    
    Private Sub radioDetails_CheckedChanged(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles radioDetails.CheckedChanged
        ListView1.View = View.Details
    End Sub

    Private Sub radioList_CheckedChanged(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles radioList.CheckedChanged
        ListView1.View = View.List
    End Sub

    Private Sub radioLarge_CheckedChanged(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles radioLarge.CheckedChanged
        ListView1.View = View.LargeIcon
    End Sub

    Private Sub radioSmall_CheckedChanged(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles radioSmall.CheckedChanged
        ListView1.View = View.SmallIcon
    End Sub
    
Ultimo aggiornamento 13/01/2004