;

terça-feira, 4 de janeiro de 2011

Como criar um gridview com linhas duplas

Este é mais um artigo voltado para quem desenvolve aplicações web. Aborda o controle gridview do asp.net. Para quem ainda não conhece, o gridview é um controle que exibe uma listagem de dados em forma de tabela. Possui diversos métodos e propriedade que torna seu manuseio bastante prático. Para saber mais sobre gridview, consulte a página do MSDN.

Porém outro dia tive a necessidade de desenvolver uma lista, ou tabela, que exibisse duas linhas por registro. Cada linha da tabela seria composta por dois níveis: no primeiro nível tinha que exibir alguns campos do registro, e no segundo nível tinha uma descrição textual do item, mais ou menos conforme a ilustração abaixo:

Tabela com linhas duplas

Uma forma de fazer seria utilizar tabelas aninhadas. Porém o gridview facilita a carga de dados do lado do servidor, quando por exemplo consultamos dados em uma base de dados, e até permite aninhar gridviews, mas não atendia minha necessidade. Para resolver o dilema utilizei as duas soluções: gridview e tabela. Utilizei um gridview por causa de sua praticidade, e inseri tabelas (tags <table> do HTML) para criar o efeito de duas linhas por registro. Veja como ficou o HTML: 

 <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    onrowdatabound="GridView1_RowDataBound">
    <AlternatingRowStyle CssClass="alternado1" />
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:Literal runat="server" ID="ltr"></asp:Literal>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

Se você reparar bem, este grid só tem uma coluna “template field” com um controle asp:literal nesta coluna. Mas não tem as tabelas aninhadas para dar o efeito de linhas duplas. Ainda não tem, mas vai ter na hora que for renderizado. Como? Tratanto o evento OnRowDataBound. Este evento é invocado ao chamar o método DataBind do gridview. Este é o código do evento:

protected void GridView1_RowDataBound(object sender,GridViewRowEventArgs e)
{
    if (e.Row.RowIndex == -1) //monta o cabeçalho
       e.Row.Cells[0].Text =
           montaCabecalho(((DataView)GridView1. DataSource).Table);
    else // monta cada linha
        ((Literal)e.Row.Cells[0].Controls[1]).Text = montaLinha(((DataView)GridView1.DataSource).Table.Rows[e.Row.RowIndex]);
}

Para cada linha do grid montamos uma tabela, que será atribuída ao controle asp:literal de cada linha deste grid. Os métodos que montam estas tabelas são estes:

 /// <summary>
/// Monta o cabeçalho do grid, baseado no nome das colunas da
/// dataview do source do grid
/// </summary>
/// <param name="tabela">Data com o resultado da consulta no banco
/// de dados</param>
/// <returns>Código HTML que representa o cabeçalho do grid</returns> 
private string montaCabecalho(DataTable  tabela)
{
StringBuilder ret =  new StringBuilder("<table class='cabec'><tr>");

    for (int i = 0; i < tabela.Columns.Count - 1; i++)
        ret.Append( "<td>" + tabela.Columns[i].ToString() + "</td>");

    ret.Append( "</tr></table>");
    return ret.ToString();
}

/// <summary>
/// Monta o cada linha do grid, de acordo com os registros
/// da dataview que é alimentada com a consulta na database
/// </summary>
/// <param name="linha">O registro a ser formatado</param>
/// <returns>Código HTML da respectiva linha</returns>
private string montaLinha(DataRow linha)
{
    StringBuilder ret =  new StringBuilder("<table class='corpo'><tr>");

    //monta a linha de primeiro nível do registro
    for (int i = 0; i < linha.ItemArray.Length - 1; i++)
        ret.Append("<td class='colcima'>" + linha[i].ToString() + "</td>");

    ret.Append("</tr>");

    //monta a linha de segundo nível do registro
    ret.Append("<tr><td colspan='3'>" + linha[linha.ItemArray.Length–1].
                                        ToString() + "</td></tr>");
    ret.Append("</table>");

    return ret.ToString();
}

Agora já temos um gridview com linhas duplas. Para alinhar todos os campos, deixar o grid com um visual mais agradável e aplicar alguns efeitos, basta definir os estilos CSS. Eu utilizei estes:
 
<style type="text/css">
    .cabec {width:100%; text-align:left; background-color:#dddddd;}
    .cabec td {width:33%;}
    .corpo {width:100%; cursor:pointer;}
    .corpo :hover {background-color:#ccccaa;}
    .colcima {width:33%}
    .alternado1 {background-color:#dddddd;}
</style>
 
O resultado final ficou assim:

Gridview com linhas com duas linhas por registro

0 comentários:

Postar um comentário