Caro leitor, hoje gostaria de mostrar e falar sobre como ordenar suas colunas com apenas um clique, sem precisar ir ao banco de dados novamente.

Tag: C#, ASP.NET, .NET, Visual Studio 2010

Para quem desenvolve software utilizando a plataforma da Microsoft,  usa muito o component GridView. Esse componente serve para listar todos dados vindos de um banco de dados qualquer, pode ser SQL Server, MySQL, Oracle, Sybase e outros.

Este componente é muito poderoso e te ajuda a listar os dados de forma simples e dinâmica. Existe um evento dentro desse objeto chamado Sort que serve para ordenar a coluna toda por ordem alfabética crescente ou decrescente. 

Hoje para preencher um GridView, é necessário atribuir as colunas, ter dados do XML ou  banco de dados ou tabelas em Excel ou qualquer outro meio de armazenamento de dados. No final, é necessário ter um DataSet ou DataTable preenchido para passar ao objeto GriView.

O meu objetivo aqui não é mostrar passo a passo como preencher um gridview, o objetivo é ordenar os dados preenchidos do seu grid.

O primeiro passo é colocar o seu grid na página .aspx. (Code 1)

<asp:GridView ID="grdContaCorrente" runat="server" Width="985px" PageSize="27" BackColor="White" 
                    BorderColor="#EEEEEE" BorderStyle="Solid" BorderWidth="2px" CellPadding="3"
                    CellSpacing="1" GridLines="Horizontal" AllowPaging="True" AllowSorting="true" 
                    AutoGenerateColumns="False" 
                    onpageindexchanging="grdContaCorrente_PageIndexChanging" 
                    onselectedindexchanged="grdContaCorrente_SelectedIndexChanged" 
                    onrowcreated="grdContaCorrente_RowCreated" 
                onsorting="grdContaCorrente_Sorting">

                    <FooterStyle BackColor="White" ForeColor="#000066" BorderStyle="Solid" />
                    <PagerStyle BackColor="White" ForeColor="#000066" HorizontalAlign="Left" BorderStyle="Solid" />
                    <SelectedRowStyle BackColor="#A0A4AC" Font-Bold="True" ForeColor="White" BorderStyle="Solid" />
                    <HeaderStyle BackColor="#D84040" Font-Bold="True" ForeColor="White" BorderStyle="Solid" />
                    <AlternatingRowStyle BackColor="#EEEEEE" BorderStyle="Solid" />    
        
                    <Columns>
                        <asp:CommandField SelectText="»»" ShowCancelButton="False" ShowSelectButton="True">
                            <ItemStyle BorderStyle="Solid" BorderWidth="2px" HorizontalAlign="Center" VerticalAlign="Middle" Width="1px" />
                        </asp:CommandField>
                        <asp:BoundField SortExpression="Agencia" DataField="Agencia" HeaderText="Agência" HtmlEncode="False" FooterText="">
                            <ItemStyle BorderStyle="Solid" BorderWidth="2px" HorizontalAlign="Center" VerticalAlign="Middle"/>
                        </asp:BoundField>
                        <asp:BoundField SortExpression="Conta" DataField="Conta" HeaderText="Conta" HtmlEncode="False" FooterText="">
                            <ItemStyle BorderStyle="Solid" BorderWidth="2px" HorizontalAlign="Center" VerticalAlign="Middle"/>
                        </asp:BoundField>
                        <asp:BoundField SortExpression="Nome" DataField="Nome" HeaderText="Nome" HtmlEncode="False" FooterText="">
                            <ItemStyle BorderStyle="Solid" BorderWidth="2px" HorizontalAlign="Left" VerticalAlign="Middle" />
                        </asp:BoundField>
                        <asp:BoundField SortExpression="CPFCNPJ" DataField="CPFCNPJ" HeaderText="CPF/CNPJ" HtmlEncode="False" FooterText="">
                            <ItemStyle BorderStyle="Solid" BorderWidth="2px" HorizontalAlign="Center" VerticalAlign="Middle" />
                        </asp:BoundField>
                        <asp:BoundField SortExpression="ContaConjunta" DataField="ContaConjunta" HeaderText="C. Conjunta" HtmlEncode="False" FooterText="">
                            <ItemStyle BorderStyle="Solid" BorderWidth="2px" HorizontalAlign="Center" VerticalAlign="Middle" />
                        </asp:BoundField>
                        <asp:BoundField SortExpression="DataCadastro" DataField="DataCadastro" HeaderText="Data Cadastro" HtmlEncode="False" FooterText="">
                            <ItemStyle BorderStyle="Solid" BorderWidth="2px" HorizontalAlign="Center" VerticalAlign="Middle" />
                        </asp:BoundField>
                        <asp:BoundField SortExpression="Situacao" DataField="Situacao" HeaderText="Situação" HtmlEncode="False" FooterText="">
                            <ItemStyle BorderStyle="Solid" BorderWidth="2px" HorizontalAlign="Center" VerticalAlign="Middle" />
                        </asp:BoundField>
                        <asp:BoundField SortExpression="SituacaoConciliacao" DataField="SituacaoConciliacao" HeaderText="Sit. Conciliação" HtmlEncode="False" FooterText="">
                            <ItemStyle BorderStyle="Solid" BorderWidth="2px" HorizontalAlign="Center" VerticalAlign="Middle" />
                        </asp:BoundField>
                        <asp:BoundField DataField="ContaCorrenteId" HeaderText="ContaCorrenteId" />
                    </Columns>
                    <HeaderStyle Font-Size="Smaller" />
                    <PagerStyle Font-Size="Smaller" />
                    <RowStyle Font-Size="Smaller" />
                    <PagerSettings Position="Bottom" Mode="NextPreviousFirstLast" 
                        PreviousPageText="<img src='imagens/seta-esquerda.png' border='0' title='Página Anterior'/>" 
                        NextPageText="<img src='imagens/seta-direita.png' border='0' title='Próxima Página'/>" 
                        FirstPageText="<img src='imagens/seta-esquerda-ultima.png' border='0' title='Primeira Página'/>" 
                        LastPageText="<img src='imagens/seta-direita-ultima.png' border='0' title='Última Página'/>" PageButtonCount="27" />
            </asp:GridView>
Code 1

Note que o meu grid possui muitos campos como: Agência, Conta, Nome, CPFCNPJ, ContaConjunta, DataCadastro e Situacao. 

O segundo passo foi colocar no gridview uma tag chamada AllowSorting=”true”, permite que as colunas sejam ordenadas. Isso não é tudo, é necessário seguir outros passos importantes que vem a seguir. 

O terceiro passo foi colocar em cada coluna uma tag chamada SortExpression=”NOME_DA_COLUNA”. O mesmo nome da coluna existente em seu objeto de dados. 

Além desses passos, preciso gerar um evento do próprio GridView. Esse evento chama OnSorting. Escolha na parte de Design e clique no botão Events localizado nas propriedades (properties). Imagem 1.



Imagem 1

Note que a imagem está selecionada no evento Sorting. Basta clicar duas vezes em cima que, automaticamente um método é criado. (Code 2)

protected void grdContaCorrente_Sorting(object sender, GridViewSortEventArgs e)
{}
Code 2

Para pegar o nome da coluna selecionada pelo usuário, basta utilizar o código seguinte. (Code 3)
String _coluna = e.SortExpression;

Depois de ter o nome da coluna fica mais fácil fazer a ordenação. Na verdade é a principal etapa para ordenação, você precisa saber qual a coluna que o usuário clicou para ordenar. 

O quarto passo é ordenar os valores e preencher novamente o GridView. Muitos desenvolvedores escrevem o código indo novamente ao banco de dados. Não é errado fazer isso, porém, para evitar ir ao banco de dados a todo o momento e consumir muito tráfego na rede; é melhor ordenar o objeto de dados em vez de ir ao banco.

Você pode armazenar no ViewState ou em Sessão todo o objeto de dados que no meu caso é um DataTable. Lembre-se que se o ViewState for muito grande, pode dar o erro sem memória. Para evitar isso, resolvi armazenar o meu DataTable em uma Sessão temporária. Code 4.

Session.Add("TEMP_SESSAO", _dtTable);
Code 4

Para pegar essa Sessão novamente basta fazer da seguinte forma. Code 5.
DataTable _dtTable = (DataTable)Session["TEMP_SESSAO"];
Code 5

Estou utilizando apenas um cast para transformar a sessão em DataTable novamente. Existem dois artigos escritos anteriormente que mostram como ordenar os dados no objeto. Segue o link dos dois: 


Nos dois links acima eu mostro como ordenar um objeto.  Code 6.
String _coluna = e.SortExpression;
_dtTable.DefaultView.Sort = _coluna;

this.grdContaCorrente.DataSource = _dtTable;
this.grdContaCorrente.DataBind();
Code 6

O problema maior agora é fazer com que a ordem seja crescente ou decrescente. Pra isso é necessário armazenar a coluna anterior clicada, se a coluna for igual a última selecionada, basta acrescentar o desc. Criei um campo hidden na tela para armazenamento e depois fiz a verificação com a condição if. Veja o Code 7.

protected void grdContaCorrente_Sorting(object sender, GridViewSortEventArgs e)
    {
        try
        {
            DataTable _dtTable = (DataTable)Session["TEMP_SESSAO"];
            String _coluna = e.SortExpression;

            if (_coluna.Equals(hdColuna.Value))
                _coluna = _coluna + " desc";

            hdColuna.Value = _coluna;
            _dtTable.DefaultView.Sort = _coluna;

            this.grdContaCorrente.DataSource = _dtTable;
            this.grdContaCorrente.DataBind();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
Code 7

Depois de pegar a sessão, pego a coluna e armazeno na variável “_coluna”. Verifico com o if(_coluna.Equals(hdColuna.Value)) se o valor é o mesmo selecionado anteriormente. Se for igual, eu coloco o “ desc” e adiciono no campo hidden. O comando DefaultView.Sort = _coluna significa que os dados estão sendo ordenados pela coluna passada e depois o DataSource do grid recebe o objeto DataTable re-ordenado. 

Dessa maneira não vou ao banco de dados e ordeno todo o meu objeto com um clique.
Espero que tenha gostado e qualquer dúvida pode entrar em contato.