Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
Guida al Visual Basic .NET - ListView

Guida al Visual Basic .NET

Capitolo 66° - ListView

<< Precedente Prossimo >>

La ListView è un controllo complesso e di grande impatto visivo. È lo stesso tipo di lista usato dall'explorer di windows per visualizzare files e cartelle. Le sue proprietà permettono di personalizzarne la visualizzazione in cinque stili diversi: i più importanti di questi sono Large Icone (Icone grandi), Small Icon (Icone piccole) e Details (Dettagli). Ci sono poi anche Tile e List, ma vengono usati meno spesso. Ecco alcuni esempi:

ListView1.jpg

Large Icon


ListView2.jpg

Small Icon


ListView3.jpg

Details



ListView

Come al solito, ecco la compilation delle proprietà più interessanti:

  • CheckBoxes : indica se la listview debba visualizzare delle CheckBox vicino ad ogni elemento
  • Columns : collezione delle colonne disponibili. Ogni colonna è contraddistinta da un testo (Text), un indice d'immagine (ImageIndex) e un indice di visualizzazione (DisplayIndex) che specifica la sua posizione ordinale nella visualizzazione. Le colonne sono visibili sono con View = Details
  • FullRowSelect : indica se evidenziare tutta la riga o solo il primo elemento, quando View = Details
  • GridLines : indica su visualizzare le righe della griglia, quando View = Details
  • Groups : collezione dei gruppi disponibili
  • HeaderStyle : specifica se le intestazioni delle colonne possano essere cliccate o meno
  • HideSelection : specifica se la listview debba nascondere la selezione quando perde il Focus, ossia quando un altro controllo diventa il controllo attivo
  • HotTracking : abilita gli elementi ad apparire come collegamenti ipertestuali quando il mouse ci passa sopra
  • HoverSelection : se impostata su True, sarà possibile selezionare un elemento semplicemente sostandoci sopra con il mouse
  • Items : collezione degli elementi della listview
  • LabelEdit : specifica se sia possibile modificare il testo dei SubItems da parte dell'utente, quando View = Details
  • LargeImageList : ImageList per View = Large Icon / Tile / List
  • MultiSelect : indica se si possano selezionare più elementi contemporaneamente
  • OwnerDraw : indica se gli elementi debbano essere disegnati dal controllo o dal codice del programmatore. Vedi articolo relativo
  • ShowGroups : determina se visualizzare i gruppi
  • ShowItemToolTips : determina se visualizzare i ToolTips dei rispettivi elementi
  • SmallIconList : ImageList per View = Small Icon / Details
  • Sorting : il tipo di ordinamento, se alfabetico ascendente o discendente.

 

ListViewItem

  Ogni elemento della ListView è contraddistinto da un oggetto ListViewItem, che, a differenza di quanto avveniva cone le normali liste come ListBox e ComboBox, non costituisce una semplice stringa (o un tipo base facilmente rappresentabile) ma un nucleo a sè stante, del quale si possono personalizzare tutte le caratteristiche visive e stilistiche. Poichè la ListView è compatibile con l'ImageList, tutti i membri della collezione Items sono in grado di impostare l'indice d'immagine associato, come si è analizzato nella lezione scorsa. Inoltre, sempre manipolando le proprietà, si può attribuire ad ogni elemento un testo, un font, un colore diverso a seconda delle necessità. Nella visualizzazione a dettagli si possono impostare tutti i valori corrispettivi ad ogni colonna mediante la proprietà SubItems, la quale contiene una collezione di oggetti ListViewSubItem: di questi è possibile modificare il font e il colore, oltre che il testo.

ListViewGroup

Un gruppo è un insieme di elementi raggruppati sotto la stessa etichetta. I gruppi vengono aggiunti alla lista utilizzando l'apposita proprietà Groups e ogni elemento può essere assegnato ad un gruppo con la stessa proprietà (ListViewItem.Group). Oggetti di questo tipo godono di poche caratteristiche: solo il testo ed il nome sono modificabili. Prima di procedere con ogni operazione, però, bisogna assicurarsi che la proprietà ShowGroups della ListView sia impostata a True, altrimenti... beh, niente festa.
Ecco un esempio di codice:

'Nuovo gruppo 'Testo esplicativo'
Dim G As New ListViewGroup("Testo esplicativo")
'Nuovo elemento 'Elemento'
Dim L As New ListViewItem("Elemento")
'Aggiunge il gruppo alla listview
ListView1.Groups.Add(G)
'Setta il gruppo a cui L apparterrà
L.Group = G
'Aggiunge l'elemento alla lista
ListView1.Items.Add(L) 

 

ListView con View = Details

La ListView a dettagli è la versione più complessa di questo controllo, ed è contraddistinta dalla classica visualizzazione a colonne. Ogni colonna viene determinata in fase di sviluppo o a run-time agendo sulla collezione Columns nelle proprietà della lista e bisogna ricordare l'ordine in cui le colonne vengono inserite poichè questo influisce in maniera significativa sul comportamento dei SubItems. Infatti il primo SubItem di un ListViewItem andrà sotto la prima colonna, quella con indice 0, il secondo sotto la seconda e così via. Un errore di ordine potrebbe produrre quindi, risultati sgradevoli. Nell'esempio che segue, scriverò un breve programma per calcolare la spesa totale conoscendo i singoli prodotti e le singole quantità di una lista della spesa. Ecco un'anteprima di come dovrebbe apparire la finestra:

ListView4.jpg
I controlli usati sono deducibili dal nome e dall'utilizzo. Ecco quindi il codice:

Class Form1
    Private Sub cmdAdd_Click(ByVal sender As System.Object, _ 
        ByVal e As System.EventArgs) Handles cmdAdd.Click
        'Nuovo elemento
        Dim Item As ListViewItem
        'Array dei valori che andranno a rappresentare i campi di
        'ogni singola colonna
        Dim Values() As String = _
            {txtProduct.Text, nudPrice.Value, nudQuantity.Value}

        'Inizializza Item sulla base dei valori dati
        Item = New ListViewItem(Values)
        'E lo aggiunge alla lista
        lstProducts.Items.Add(Item)
    End Sub

    Private Sub cmdDelSelected_Click(ByVal sender As System.Object, _ 
        ByVal e As System.EventArgs) Handles cmdDelSelected.Click
        'Analizza tutti gli elementi selezionati
        For Each SelItem As ListViewItem In lstProducts.SelectedItems
            'E li rimuove dalla lista
            lstProducts.Items.Remove(SelItem)
        Next
    End Sub

    Private Sub cmdCalculate_Click(ByVal sender As System.Object, _ 
        ByVal e As System.EventArgs) Handles cmdCalculate.Click
        'Totale spesa
        Dim Total As Single = 0
        'Prezzo unitario
        Dim Price As Single
        'Quantit?
        Dim Quantity As Int32

        For Each Item As ListViewItem In lstProducts.Items
            'Ottiene i valori da ogni elemento
            Price = CSng(Item.SubItems(1).Text)
            Quantity = CInt(Item.SubItems(2).Text)
            Total += Price * Quantity
        Next

        MessageBox.Show("Totale della spesa: " & Total & ".", _
            "Spesa", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End Sub
End Class 

Per i più curiosi, mi addentrerò ancora un pò di più nel particolare, nella fattispecie su una caratteristica molto apprezzata in una ListView a dettagli, ossia la possibilità di ordinare tutti gli elementi con un click. In questo caso, facendo click sull'intestazione (header) di una colonna, sarebbe possibile ordinare gli elementi sulla base della qualità che quella colonna espone: per nome, per prezzo, per quantità. Dato che il metodo Sort non accetta alcun overload che consenta di usare un Comparer, bisognerà implementare un algoritmo che compari tutti gli elementi e li ordini. In questo esempio si fa ricorso a due classi che implementano l'interfaccia generica IComparer(Of ListViewItem): il primo compara il nome del prodotto, mentre il secondo il prezzo e la quantità. Ecco il codice da aggiungere:

Class Form1
    'Queste classi saranno i comparer usati per ordinare
    'le righe della ListView, al pari di come si è imparato nelle
    'lezioni sulle interfacce
    Private Class ProductComparer
        Implements IComparer(Of ListViewItem)

        Public Function Compare(ByVal x As ListViewItem, _ 
            ByVal y As ListViewItem) As Integer _
            Implements IComparer(Of ListViewItem).Compare
            'Gli oggetti da comparare sono ListViewItem, mentre la proprietà
            'che bisogna confrontare è il nome del prodotto, ossia
            'il primo sotto-elemento
            Dim Name1 As String = x.SubItems(0).Text
            Dim Name2 As String = y.SubItems(0).Text
            Return Name1.CompareTo(Name2)
        End Function
    End Class

    Private Class NumberComparer
        Implements IComparer(Of ListViewItem)

        Private Index As Int32

        'Price è True se ci si riferisce al Prezzo (elemento 1)
        'oppure False se ci si riferisce alla quantità (elemento 2)
        Sub New(ByVal Price As Boolean)
            If Price Then
                Index = 1
            Else
                Index = 2
            End If
        End Sub

        Public Function Compare(ByVal x As ListViewItem, _ 
            ByVal y As ListViewItem) As Integer _
            Implements IComparer(Of ListViewItem).Compare
            'Qui bisogna ottenere il prezzo o la quantità: ci si basa
            'sul parametro passato al costruttore
            Dim Val1 As Single = x.SubItems(Index).Text
            Dim Val2 As Single = y.SubItems(Index).Text
            Return Val1.CompareTo(Val2)
        End Function
    End Class

    'Scambia due elementi in una lista: dato che ListViewItem sono 
    'variabili reference, bisognerebbe clonarli per spostarne il valore, 
    'come si faceva con i valori value, in questo modo:
    'Dim Temp As ListViewItem = L1.Clone()
    'L1 = L2.Clone()
    'L2 = Temp
    'Ma si userebbe troppa memoria. Perciò la via più facile è
    'usare i metodi della lista per scambiare gli elementi
    Private Sub SwapInList(ByVal List As ListView, ByVal Index As Int32)
        Dim Temp As ListViewItem = List.Items(Index + 1)
        List.Items.RemoveAt(Index + 1)
        List.Items.INSERT IGNORE(Index, Temp)
    End Sub

    'Ordina gli elementi con l'algoritmo Bubble Sort già
    'descritto nell'ultima lezione teorica
    Private Sub SortListViewItems(ByVal List As ListView, _
        ByVal Comparer As IComparer(Of ListViewItem))
        Dim Occurrences As Int32 = 0

        Do
            Occurrences = 0
            For I As Int32 = 0 To List.Items.Count - 1
                If I = List.Items.Count - 1 Then
                    Continue For
                End If
                If Comparer.Compare(List.Items(I), List.Items(I + 1)) = 1 Then
                    SwapInList(List, I)
                    Occurrences += 1
                End If
            Next
        Loop Until Occurrences = 0
    End Sub
    
    Private Sub lstProducts_ColumnClick(ByVal sender As System.Object,  _
        ByVal e As ColumnClickEventArgs) Handles lstProducts.ColumnClick
        Select Case e.Column
            Case 0
                'Nome
                Me.SortListViewItems(lstProducts, New ProductComparer())
            Case 1
                'Prezzo
                Me.SortListViewItems(lstProducts, New NumberComparer(True))
            Case 2
                'Quantità
                Me.SortListViewItems(lstProducts, New NumberComparer(False))
        End Select
    End Sub
End Class 
<< Precedente Prossimo >>
A proposito dell'autore

Programmatore e analista .NET 2005/2008/2010 (in particolare C# e VB.NET), anche nell'implementazione Mono per Linux. Conoscenze approfondite di Pascal, PHP, XML, HTML 4.01/5, CSS 2.1/3, Javascript (e jQuery). Conoscenze buone di C, LUA, GML, Ruby, XNA, AJAX e Assembly 68000. Competenze basilari di C++, SQL, Hlsl, Java.