En este artículo veremos como se crea la siguiente lista:

Hay que empezar por olvidarnos de mucho de lo que conocíamos del ListView de las versiones previas de Visual Studio. En primer lugar, no existe una colección de SubItems asociada a cada Item, tampoco tenemos las clásicas vistas para mostrar íconos grandes, medianos y pequeños o la clásica vista “Report”, para mostrar varias columnas. Estas son las dos primeras grandes diferencias que inicialmente saltan a la vista y que tendremos que aprender a sortear.
Agregar elementos
La forma más sencilla de agregar Items, si se mantiene tal como la conocíamos y es la siguiente:
lstBooks.Items.Add("Pro WPF with VB 2008")
De tal manera que es posible añadir cadenas para verlas directamente dentro de la lista.
Un poco más complicado resulta si queremos agregar elementos que luego se puedan mostrar en un listado multicolumna. Y es aquí donde no hará más falta utilizar la colección SubItems, ya que en su lugar, podemos agregar cualquier objeto personalizado a nuestra colección de Items, tal como se ve en el siguiente ejemplo:
lstBooks.Items.Add(New bookBO("Coquito", "Ediciones Bruño", 5))
Lo que es lo mismo que:
dim book as New bookBO() book.Nombre = "Coquito" book.Editor = "Ediciones Bruño" book.Calificacion = 5 lstBooks.Items.Add(book)
En ambos casos se ha agregado un Nuevo elemento del tipo bookBO (una clase personalizada).
Visualizar la lista
Si en nuestro ListView sólo hemos agregado Strings, la visualización será inmediata; pero si es que hemos agregado elementos de una clase personalizada, tenemos dos alternativas: dotar a nuestra clase personaliza de una función ToString, que devuelva la cadena que deseamos que se muestre para cada fila de la lista; o, establecer adecuadamente la propiedad View.
Aunque la propiedad View aún se mantiene, su funcionalidad es distinta. Ahora esta propiedad se utiliza para indicar un objeto del tipo GridView (el cual es configurable) o alguna clase personalizada que se derive de ViewBase.
Si vamos a utilizar la clase GridView, podemos configurarla por código como se muestra en el siguiente ejemplo:
'Crear un objeto del tipo GridView
Dim myGridView As New GridView()
'Crear las columnas a agregar
Dim gvc1 As New GridViewColumn()
Dim gvc2 As New GridViewColumn()
'Establecer las propiedades de cada columna
gvc1.Header = "Libro"
gvc1.Width = 140
gvc1.DisplayMemberBinding = New Binding("NombreLibro")
gvc2.Header = "Autor"
gvc2.Width = 240
gvc2.DisplayMemberBinding = New Binding("NombreAutor")
'Agregar las columnas al objeto GridView
myGridView.Columns.Add(gvc1)
myGridView.Columns.Add(gvc2)
'Establecer la vista del ListView
lstBooks.View = myGridView
Es importante notar la propiedad DisplayMemberBinding de cada columna. En esta propiedad se indica cual de las propiedades de nuestra clase personalizada corresponde a esa columna. Nuestra clase personalizada podría tener decenas de propiedades, pero de esta manera indicamos que sólo se muestren unas cuantas.
Como alternativa, el código de ejemplo anterior, puede ser implementado en nuestro formulario de diseño por medio del siguiente código XAML:
<ListView Name="lstBooks" Margin="0,10,0,0">
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Libro" DisplayMemberBinding="{Binding NombreLibro}" />
<GridViewColumn Width="240" Header="Autor" DisplayMemberBinding="{Binding NombreAutor}" />
</GridView>
</ListView.View>
</ListView>
Enlazar el ListView con una colección
Es posible que la información ya la tengamos disponible en una colección. En tal caso no es necesario recorrerla para leer cada item y agregarlo al ListView, sino que podemos establecer la propiedad ItemsSource:
lstBooks.ItemsSource = MyCollection
Esta posibilidad es especialmente efectiva si el objeto MyCollection es de la clase ObservableCollection, que para el ejemplo anterior se declara de la siguiente manera:
Dim MyCollection As ObservableCollection(Of bookBO)
La ventaja de utilizar una clase ObservableCollection es que cualquier cambio que se realiza en la colección es automáticamente notificado y actualizado en la lista. De no ser así, nosotros mismos tendríamos que actualizar la lista cada vez que se modifique alguno de sus elementos (tal como lo hice en algún ejemplo del patrón MVC).
Ejemplo
A continuación un ejemplo que resume algo de lo revisado en este artículo.
XAML:
<Page x:Class="ListViewSample3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ListView1" Background="CadetBlue" Name="Page1">
<Grid Height="268" Width="591">
<ListView Margin="73,50,0,0" Name="lstBooks" HorizontalAlignment="Left" Width="429" Height="196" VerticalAlignment="Top" />
</Grid>
</Page>
Código fuente del formulario:
Partial Public Class ListViewSample3
Private Sub Page1_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
createTable()
fillTable()
End Sub
Sub createTable()
Dim myGridView As New GridView()
Dim gvc1 As New GridViewColumn()
Dim gvc2 As New GridViewColumn()
gvc1.Header = "Título"
myGridView.Columns.Add(gvc1)
gvc1.Width = 200
gvc1.DisplayMemberBinding = New Binding("Titulo")
gvc2.Header = "Autor"
myGridView.Columns.Add(gvc2)
gvc2.Width = 200
gvc2.DisplayMemberBinding = New Binding("Autor")
lstBooks.View = myGridView
End Sub
Sub fillTable()
lstBooks.Items.Clear()
lstBooks.Items.Add(New bookBO("Windows Presentation Foundation Unleashed", "Adam N"))
lstBooks.Items.Add(New bookBO("Pro WPF with VB 2008", "Matthew McD"))
lstBooks.Items.Add(New bookBO("3D Programming-for-windows by WPF", "Charles P"))
End Sub
End Class
Clase BookBO:
Public Class bookBO
Public Class bookBO
Private mTitulo As String
Private mAutor As String
Public Sub New(ByVal Titulo As String, ByVal Autor As String)
mTitulo = Titulo
mAutor = Autor
End Sub
Public Property Titulo() As String
Get
Titulo = mTitulo
End Get
Set(ByVal value As String)
mTitulo = value
End Set
End Property
Public Property Autor() As String
Get
Autor = mAutor
End Get
Set(ByVal value As String)
mAutor = value
End Set
End Property
'Esta funcion no es necesaria, solo para mostrar su implementacion
Public Overrides Function ToString() As String
ToString = mTitulo + " - " + mAutor
End Function
End Class
Resultado

En el próximo artículo revisaremos como agregar controles (gráficos incluidos) dentro de un ListView y mantenerlos enlazados con nuestra clase personalizada.
Hasta pronto!
David
abril 4, 2010
No sé si sería mucho pedir un ejemplo que rellenara el listview con datos de una tabla access.
Llevo días dándole vueltas y no hay manera. Sería un buen contenido para el blog.
Gracias y felicidades por la página.
zameb
abril 6, 2010
Hola David, gracias por tus comentarios, por ahora tratare de ayudarte con esta respuesta, mientras me hago tiempo de preparar nuevas entradas.
Pondre los ejemplos en C#, pero luego convertirlo a VB.NET no es nada complicado.
Primero debes conectarte a una BD Access y abrir la conexion:
SqlConnection conn = new SqlConnection();
conn.ConnectionString = “Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\dotNetStudy\GesCon.mdb;”;
conn.Open();
Con la conexion abierta, debes ejecutar un comando que cargue un objeto Reader (te devolvera los registros):
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = “select codigo,apellido,nombre from EMP”;
SqlDataReader reader;
reader = cmd.ExecuteReader();
Luego puedes empezar a agregar alguna de las cadenas del Reader a la lista:
while (reader.Read())
{
lstEmpresa.Items.Add(reader.GetString(1));
}
Si en lugar de agregar una cadena, deseas agregar todo el objeto, ya es un poco mas complicado.
Saludos