Guida al Visual Basic .NET
Capitolo 66° - ListView
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: Large Icon
Small Icon
Details
ListView
Come al solito, ecco la compilation delle proprietà più interessanti:
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. '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: 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
C#, TypeScript, java, php, EcmaScript (JavaScript), Spring, Hibernate, React, SASS/LESS, jade, python, scikit, node.js, redux, postgres, keras, kubernetes, docker, hexo, etc...
|