Uso del control WPF-ListView – Parte 1

Posted on noviembre 8, 2009

2


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

 

listview-gridview

 

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
listview-gridview

 

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!

Posted in: dotNET, VB.NET, WPF