Cómo modificar las plantillas del control ListView desde el code-behind

Como ya seguro que todos sabréis, el control ListView fue una de las novedades de Visual Studio 2008 en lo que se refiere al desarrollo web.

Es un control que me gusta especialmente porque te deja control total sobre el HTML que genera.

El control se basa en plantillas y a través de estas se puede especificar el layout que tendrá; si se genera un tabla, una lista….todo depende de HTML que incluyas en las plantillas.

En el ejemplo que se ve a continuación el ListView renderiza una tabla con única columna y tantas filas como elementos devuelva el DataSource MenuListOds. ( sí, un ejemplo un poco tonto pero suficiente para lo que necesitamos para el ejemplo ).

MenuListOds es un ObjectDataSource que tiene un método GetList que devuelve una colección de elementos que tienen la propiedad Name. Este ObjectDataSource es el que se usa para rellenar el ListView.

<asp:ListView ID="MyListView" runat="server" DataSourceID="MenuListOds"> <LayoutTemplate> <table id="ListViewTable"> <tbody> <asp:PlaceHolder id="itemPlaceHolder" runat="server"></asp:PlaceHolder> </tbody> </table> </LayoutTemplate> <ItemTemplate> <tr> <td> <% Eval (“Name”) %> </td> </tr> </ItemTemplate> </asp:ListView>

Como veis, a través de LayoutTemplate e ItemTemplate estamos definiendo cómo queremos que se renderice, especificando el HTML concreto que se va a generar.

Pero en algunos casos no es suficiente con poder definir las plantillas de forma declarativa y necesitamos establecer las plantillas desde el código.

Para crear una plantilla desde código sólo tenemos que crear una clase que implemente  la interfaz ITemplate; una para LayoutTemplate y otra para ItemTemplate.

La plantilla LayoutTemplate para el generar el mismo HTML que en el ejemplo superior sería la siguiente:

public class LayoutTemplate : ITemplate
{
    public void InstantiateIn(Control container)
    {
        var table = new HtmlGenericControl("table") { ID = "ListViewTable" };            
        var tbody = new HtmlGenericControl("tbody");
        table.Controls.Add(tbody);

        var placeHolder = new HtmlGenericControl("PlaceHolder") { ID = "itemPlaceHolder" }; ;
        tbody.Controls.Add(placeHolder);

        container.Controls.Add(table);
    }
}

Y la plantilla para ItemTemplate:

public class ItemTemplate : ITemplate
    {
        public void InstantiateIn(Control container)
        {
            var row = new HtmlGenericControl("tr");
            var col = new HtmlGenericControl("td");
            
            row.Controls.Add(col);

            col.DataBinding += DataBinding;
            container.Controls.Add(row);
        }

        public void DataBinding(object sender, EventArgs e)
        {
            var container = (HtmlGenericControl)sender;
            var dataItem = (Entity)((ListViewDataItem)container.NamingContainer).DataItem;

            container.Controls.Add(new Literal() { Text = dataItem.Name });
        }

    }

Fijaros que esta segunda plantilla usamos el evento DataBinding, para pintar la información que nos interesa en cada columna de la fila.

Una vez creadas sólo tendremos que decir al ListView que use las plantillas que hemos creado:

LayoutTemplate template = new LayoutTemplate();
MyListView.LayoutTemplate = template;

ItemTemplate itemTemplate = new ItemTemplate();
MyListView.ItemTemplate = itemTemplate;

Espero que os sea de utilidad!

Ibon Landa

bon Landa lleva más de 15 años dedicado al desarrollo de software. Durante este tiempo ha trabajado en diferentes empresas en las cuáles ha podido trabajar en diferentes entornos y tecnologías. Actualmente está focalizado principalmente en tareas de desarrollo, arquitectura, en las herramientas del ciclo de vida y en todo lo relacionado con la plataforma de Cloud Computing Microsoft Azure, área en el que ha sido reconocido como MVP. Participa de forma activa en la comunidad, escribiendo su blog, manteniendo un portal sobre Microsoft Azure y colaborando con Microsoft y grupos de usuarios en eventos de formación, talleres y giras de producto.

2 comentarios en “Cómo modificar las plantillas del control ListView desde el code-behind”

  1. Holita,

    cómo podríamos hacer este LayoutTemplate por código ?

    Saludos y gracias




    < %//
    //miscontroles:Button ID=»DeleteButton» runat=»server» Text=»Borrar ficheros seleccionados» /> %>




Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *