Explorando o GridView – Ordenação de Registros


Quando exibimos ao cliente uma grande quantidade de dados, algumas funcionalidades se fazem essenciais para que ele possa visualizar e analisar estes dados de forma mais eficiente. Uma dessas funcionalidades é chamada de ordenação de colunas, ou Sorting.

Quando utilizamos o DataGrid da versão 1.x do ASP.NET, para poder ter esta funcionalidade, tínhamos que, através do evento SortCommand do DataGrid, recuperar a coluna que foi clicada pelo usuário e invocar novamente o procedimento que resgata os dados e popula o Datagrid, informando a coluna que será utilizada para efetuar a ordenação. Agora, com o controle GridView, conseguimos obter esta funcionalidade sem a escrita de nenhuma linha de código, salvo quando utilizamos o objeto ObjectDataSource.

Utilizando o objeto SqlDataSouce

Para habilitarmos esta funcionalidade no controle GridView utilizando o objeto SqlDataSource devemos clicar na Smart Tag e marcar o CheckBox chamado Enable Sorting, como é mostrado na imagem abaixo:

Figura 1 – Habilitando a Ordernação de Registros.

Habilitando esta opção, o controle GridView já fará a ordenação dos registros automaticamente. Através do código HTML abaixo da página ASPX, vemos como o mesmo ficou configurado:

<asp:GridView 
    ID="GridView1" 
    runat="server" 
    DataSourceID="SqlDataSource1" 
    AutoGenerateColumns="False" 
    AllowSorting="True"	
    DataKeyNames="UsuarioID">
    <Columns>
        <asp:BoundField 
            DataField="Nome" 
            HeaderText="Nome" 
            SortExpression="Nome" />
        <asp:BoundField 
            DataField="Email" 
            HeaderText="Email" />
    </Columns>
</asp:GridView>

Analisando o código acima podemos notar a propriedade SortExpression da coluna do tipo BoundField. É através desta propriedade que o ASP.NET se encarrega de ordenar a coluna automaticamente clicada pelo usuário e, no caso acima, somente a ordenação para a coluna Nome está habilitada. Algo importante à dizer é que a propriedade SortExpression deve conter exatamente o nome da coluna da fonte de dados para que a ordernação seja possível.

O objeto SqlDataSource possui um propriedade chamada DataSourceMode. Através desta propriedade você define ao objeto SqlDataSource qual será a forma, Dataset ou DataReader, que ele utilizará para resgatar os dados da base de dados. Por padrão, ou seja, quando não definimos esta propriedade, o SqlDataSource faz isso utilizando um objeto do tipo Dataset.

como já vimos acima, essa ordenação é feita automaticamente somente quando definimos a propriedade DataSourceMode como Dataset (ou quando omitimos). Quando definimos esta propriedade como DataReader, sem mais nenhuma outra configuração no objeto SqlDataSource, receberemos a seguinte exceção:

Figura 2 – Exceção causada utilizando a propriedade DataSourceMode incorretamente.

Quando definimos o objeto DataReader para recuperar os dados e quisermos também ter a ordenação dos registros, devemos fazer alguns outros ajustes no objeto SqlDataSource para alcançar este objetivo. Vamos analisá-los passo à passo abaixo:

  • A propriedade DataSourceMode: Definimos para DataReader quando queremos utilizar este para recuperar os dados da fonte de dados.

  • A propriedade SelectCommand: Por design, somente conseguimos isso utilizando uma Stored Procedure. É nesta propriedade que devemos definir o nome da Stored Procedure que será responsável por recuperar os dados.

  • A propriedade SelectCommandType: Como a propriedade SelectCommand estará armazenando uma Stored Procedure, através da SelectCommandType informaremos exatamente isso, ou seja, informar ao ASP.NET que é uma Stored Procedure ao invés de um Sql Statement.

  • A propriedade SortParameterName: É justamente o parâmetro que estará dentro da Stored Procedure e que será responsável pela ordenação. Automaticamente o ASP.NET associa o nome da coluna clicada pelo usuário (a propriedade SortExpression) como o value deste parâmetro. Nota: Não há necessidade de colocar o “@” no nome deste parâmetro.

Para exemplificar o uso do objeto DataReader para recuperar os dados através do SqlDataSource e utilizar a ordenação dos dados, abaixo é exibido o código HTML da página ASPX e a respectiva Stored Procedure (que está definida na propriedade SelectCommand):

<asp:SqlDataSource 
    ID="SqlDataSource1" 
    runat="server" 
    ConnectionString="<%$ ConnectionStrings:ConnString %>"
    DataSourceMode="DataReader"
    SortParameterName="Coluna"            
    SelectCommand="Sorting" 
    SelectCommandType="StoredProcedure">
</asp:SqlDataSource>

<asp:GridView 
    ID="GridView1" 
    runat="server" 
    DataSourceID="SqlDataSource1" 
    AutoGenerateColumns="False" 
    AllowSorting="True"	
    DataKeyNames="UsuarioID">
    <Columns>
        <asp:BoundField 
            DataField="Nome" 
            HeaderText="Nome" 
            SortExpression="Nome" />
    </Columns>
</asp:GridView>

ALTER PROCEDURE dbo.Sorting 
	@Coluna As Varchar(30)
AS
	DECLARE @Query As NVarchar(4000)
	SET @Query = 'SELECT Nome, Email, UsuarioID FROM Usuario'
	
	IF @Coluna != ''
		SET @Query = @Query + ' ORDER BY ' + @Coluna
		
	EXECUTE sp_executesql @Query

Como vemos, a Stored Procedure recebe um parâmetro que será utilizado para efetuar a ordenação. Reparem que o nome do parâmetro da Stored Procedure é o mesmo que está definido na propriedade SortParameterName do objeto SqlDataSource. A verificação do valor deste parâmetro, se é ou não vazio, é necessária pois a primeira vez que a página for carregada não é passado nenhum valor à ele.

Utilizando o objeto ObjectDataSouce

Ao contrário do objeto SqlDataSouce, o objeto ObjectDataSouce necessita de algum código adicional justamente porque o mesmo está ligado à uma classe de regras negócios, a qual deve contemplar a ordenação de um result-set qualquer. O processo de ordenação para o objeto ObjectDataSource é basicamente idêntico ao mostrado acima com o objeto SqlDataSource, apenas contemplando nos parâmetros do método que retorna a coleção de objetos uma string que representará a coluna à ser ordenada.

Como a parte de vinculação do objeto ObjectDataSouce ao controle GridView é semelhante à forma acima, vamos diretamente analisar o código que será responsável pela ordenação de registros:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web.Configuration;
using System.Collections.Generic;

public class Usuarios
{
    public List<Usuario> ResgataUsuarios() {
        return ResgataUsuarios(string.Empty);
    }

    public List<Usuario> ResgataUsuarios(string coluna) {
        List<Usuario> coll = new List<Usuario>();
        string connString = 
          WebConfigurationManager.ConnectionStrings["ConnString"].ConnectionString
        SqlConnection conn = new SqlConnection(connString);
        string query = "SELECT UsuarioID, Nome, Email FROM Usuario";

        if(coluna != string.Empty)
            query += " ORDER BY " + coluna;

        SqlCommand cmd = new SqlCommand(query, conn);
        SqlDataReader dr = null;
        try
        {
            conn.Open();
            dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            while(dr.Read()){
                Usuario u = new Usuario();
                u.ID = dr.GetInt32(0);
                u.Nome = dr.GetString(1);
                u.Email = dr.GetString(2);
                coll.Add(u);
            }
        }
        finally {
            if (dr != null)
                dr.Close();
        }
        return coll;
    }
}

Analisando o código acima temos sobrecarga para o método ResgataUsuarios, onde em um deles recebemos uma string que corresponde à coluna a ser ordenada. Como fizemos com a Stored Procedure, neste método também analisamos se o parâmetro é ou não vazio pois, a partir disto, acrescentamos a cláusula ORDER BY, se necessário. Há ainda pequenas configurações a serem feitas no objeto ObjectDataSource, ou seja, no caso deste objeto, em sua Smart Tag, não temos o CheckBox para habilitar a Ordenação, tendo assim que recorrer à janela de propriedade e marcar a propriedade AllowSorting como True.

Além disso precisamos também definir a propriedade SortParameterName onde, neste caso, irá o nome do parâmetro responsável pela ordenação do nosso método ResgataUsuarios, que é coluna. Vejamos abaixo o código HTML resultante na página ASPX depois dessas configurações:

<asp:ObjectDataSource 
    ID="ObjectDataSource1" 
    runat="server" 
    SelectMethod="ResgataUsuarios"
    SortParameterName="coluna"
    TypeName="Usuarios">
</asp:ObjectDataSource>

<asp:GridView 
    ID="GridView1" 
    runat="server" 
    AutoGenerateColumns="False" 
    DataSourceID="ObjectDataSource1" 
    AllowSorting="True">
    <Columns>
        <asp:BoundField 
            DataField="Nome" 
            HeaderText="Nome" 
            SortExpression="Nome" />
    </Columns>
</asp:GridView>

Automaticamente em runtime, o ASP.NET define o valor da propriedade SortExpression clicada pelo usuário como value do parâmetro do método ResgataUsuarios. Essa atribuição é possível pois já temos mapeado na propriedade SortParameterName o nome do parâmetro responsável pela ordenação do método referido.

Observação Importante: A propriedade SortParameterName é extremamente importante, independentemente de qual objeto de Data Source utilizamos no controle GridView: isso porque podemos ter vários parâmetros na Stored Procedure ou mesmo no método da classe de negócios.

GridView.zip (674.49 kb)

Deixe uma resposta