Classificação de dados em um controle DataList ou Repeater (C#)
por Scott Mitchell
Neste tutorial, examinaremos como incluir o suporte de classificação no DataList e repeater, bem como como construir um DataList ou Repeater cujos dados podem ser paginados e classificados.
Introdução
No tutorial anterior , examinamos como adicionar suporte à paginação a um DataList. Criamos um novo método na ProductsBLL
classe (GetProductsAsPagedDataSource
) que retornou um PagedDataSource
objeto . Quando associado a um DataList ou Repeater, o DataList ou Repeater exibiria apenas a página de dados solicitada. Essa técnica é semelhante ao que é usado internamente pelos controles GridView, DetailsView e FormView para fornecer sua funcionalidade de paginação padrão interna.
Além de oferecer suporte à paginação, o GridView também inclui suporte de classificação pronto para uso. Nem o DataList nem o Repeater fornecem funcionalidade de classificação interna; no entanto, os recursos de classificação podem ser adicionados com um pouco de código. Neste tutorial, examinaremos como incluir o suporte de classificação no DataList e repeater, bem como como construir um DataList ou Repeater cujos dados podem ser paginados e classificados.
Uma revisão de classificação
Como vimos no tutorial Paginação e Classificação de Dados do Relatório , o controle GridView fornece suporte de classificação pronto para uso. Cada campo GridView pode ter um associado SortExpression
, que indica o campo de dados pelo qual classificar os dados. Quando a propriedade gridView é AllowSorting
definida true
como , cada campo GridView que tem um SortExpression
valor de propriedade tem seu cabeçalho renderizado como um LinkButton. Quando um usuário clica em um determinado cabeçalho do campo GridView, ocorre um postback e os dados são classificados de acordo com o campo clicado s SortExpression
.
O controle GridView também tem uma SortExpression
propriedade , que armazena o SortExpression
do campo GridView pelo qual os dados são classificados. Além disso, uma SortDirection
propriedade indica se os dados devem ser classificados em ordem crescente ou decrescente (se um usuário clicar em um link de cabeçalho do campo GridView específico duas vezes seguidas, a ordem de classificação será alternada).
Quando o GridView está associado ao controle da fonte de dados, ele entrega suas SortExpression
propriedades e SortDirection
ao controle da fonte de dados. O controle da fonte de dados recupera os dados e os classifica de acordo com as propriedades fornecidas SortExpression
e SortDirection
. Depois de classificar os dados, o controle da fonte de dados os retorna para o GridView.
Para replicar essa funcionalidade com os controles DataList ou Repeater, devemos:
- Criar uma interface de classificação
- Lembre-se do campo de dados pelo qual classificar e se deseja classificar em ordem crescente ou decrescente
- Instruir o ObjectDataSource a classificar os dados por um campo de dados específico
Abordaremos essas três tarefas nas etapas 3 e 4. Depois disso, examinaremos como incluir suporte de paginação e classificação em um DataList ou Repeater.
Etapa 2: Exibindo os produtos em um repetidor
Antes de nos preocuparmos em implementar qualquer uma das funcionalidades relacionadas à classificação, vamos começar listando os produtos em um controle Repeater. Comece abrindo a Sorting.aspx
página na PagingSortingDataListRepeater
pasta . Adicione um controle Repeater à página da Web, definindo sua ID
propriedade SortableProducts
como . Na marca inteligente Repeater s, crie um novo ObjectDataSource chamado ProductsDataSource
e configure-o para recuperar dados do ProductsBLL
método da classe s GetProducts()
. Selecione a opção (Nenhum) nas listas suspensas nas guias INSERT, UPDATE e DELETE.
Figura 1: Criar um ObjectDataSource e configurá-lo para usar o GetProductsAsPagedDataSource()
método (clique para exibir a imagem em tamanho real)
Figura 2: Definir o Drop-Down Listas nas guias UPDATE, INSERT e DELETE como (Nenhum) (Clique para exibir a imagem em tamanho real)
Ao contrário do DataList, o Visual Studio não cria automaticamente um ItemTemplate
para o controle Repeater depois de vinculá-lo a uma fonte de dados. Além disso, devemos adicioná-lo ItemTemplate
declarativamente, pois a marca inteligente do controle Repeater não tem a opção Editar Modelos encontrada na lista de dados. Vamos usar o mesmo ItemTemplate
do tutorial anterior, que exibiu o nome, o fornecedor e a categoria do produto.
Depois de adicionar o ItemTemplate
, a marcação declarativa de Repeater e ObjectDataSource deve ser semelhante à seguinte:
<asp:Repeater ID="SortableProducts" DataSourceID="ProductsDataSource"
EnableViewState="False" runat="server">
<ItemTemplate>
<h4><asp:Label ID="ProductNameLabel" runat="server"
Text='<%# Eval("ProductName") %>'></asp:Label></h4>
Category:
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Eval("CategoryName") %>'></asp:Label><br />
Supplier:
<asp:Label ID="SupplierNameLabel" runat="server"
Text='<%# Eval("SupplierName") %>'></asp:Label><br />
<br />
<br />
</ItemTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
SelectMethod="GetProducts">
</asp:ObjectDataSource>
A Figura 3 mostra essa página quando exibida por meio de um navegador.
Figura 3: Cada Nome, Fornecedor e Categoria de Cada Produto é Exibido (Clique para exibir a imagem em tamanho real)
Etapa 3: Instruindo o ObjectDataSource a classificar os dados
Para classificar os dados exibidos no Repeater, precisamos informar o ObjectDataSource da expressão de classificação pela qual os dados devem ser classificados. Antes que o ObjectDataSource recupere seus dados, ele primeiro dispara seu Selecting
evento, o que fornece uma oportunidade para especificarmos uma expressão de classificação. O Selecting
manipulador de eventos é passado um objeto do tipo ObjectDataSourceSelectingEventArgs
, que tem uma propriedade chamada Arguments
do tipo DataSourceSelectArguments
. A DataSourceSelectArguments
classe foi projetada para passar solicitações relacionadas a dados de um consumidor de dados para o controle da fonte de dados e inclui uma SortExpression
propriedade .
Para passar informações de classificação da página ASP.NET para o ObjectDataSource, crie um manipulador de eventos para o Selecting
evento e use o seguinte código:
protected void ProductsDataSource_Selecting
(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.Arguments.SortExpression = sortExpression;
}
O valor sortExpression deve receber o nome do campo de dados para classificar os dados por (como ProductName ). Não há nenhuma propriedade relacionada à direção de classificação, portanto, se você quiser classificar os dados em ordem decrescente, acrescente a cadeia de caracteres DESC ao valor sortExpression (como ProductName DESC ).
Vá em frente e tente alguns valores embutidos em código diferentes para sortExpression e teste os resultados em um navegador. Como mostra a Figura 4, ao usar ProductName DESC como sortExpression, os produtos são classificados por seu nome em ordem alfabética inversa.
Figura 4: Os produtos são classificados por seu nome em ordem alfabética inversa (clique para exibir a imagem em tamanho real)
Etapa 4: Criando a interface de classificação e lembrando a expressão de classificação e a direção
Ativar o suporte à classificação no GridView converte cada texto de cabeçalho de campo classificável em um LinkButton que, quando clicado, classifica os dados de acordo. Essa interface de classificação faz sentido para o GridView, em que seus dados são dispostos perfeitamente em colunas. No entanto, para os controles DataList e Repeater, é necessária uma interface de classificação diferente. Uma interface de classificação comum para uma lista de dados (em vez de uma grade de dados), é uma lista suspensa que fornece os campos pelos quais os dados podem ser classificados. Vamos implementar essa interface para este tutorial.
Adicione um controle Web DropDownList acima do SortableProducts
Repeater e defina sua ID
propriedade como SortBy
. No janela Propriedades, clique nas reticências na Items
propriedade para abrir a Editor Coleção ListItem. Adicione ListItem
s para classificar os dados pelos ProductName
campos , CategoryName
e SupplierName
. Adicione também um ListItem
para classificar os produtos pelo nome em ordem alfabética inversa.
As ListItem
Text
propriedades podem ser definidas como qualquer valor (como Nome ), mas as Value
propriedades devem ser definidas como o nome do campo de dados (como ProductName ). Para classificar os resultados em ordem decrescente, acrescente a cadeia de caracteres DESC ao nome do campo de dados, como ProductName DESC .
Figura 5: Adicionar um para cada um ListItem
dos campos de dados classificáveis
Por fim, adicione um controle Web button à direita do DropDownList. Defina como ID
RefreshRepeater
e sua Text
propriedade como Atualizar .
Depois de criar o ListItem
s e adicionar o botão Atualizar, a sintaxe declarativa de DropDownList e Button deve ser semelhante à seguinte:
<asp:DropDownList ID="SortBy" runat="server">
<asp:ListItem Value="ProductName">Name</asp:ListItem>
<asp:ListItem Value="ProductName DESC">Name (Reverse Order)
</asp:ListItem>
<asp:ListItem Value="CategoryName">Category</asp:ListItem>
<asp:ListItem Value="SupplierName">Supplier</asp:ListItem>
</asp:DropDownList>
<asp:Button runat="server" ID="RefreshRepeater" Text="Refresh" />
Com a classificação dropDownList concluída, precisamos atualizar o manipulador de eventos objectDataSource para Selecting
que ele use a propriedade s Value
selecionada SortBy``ListItem
em vez de uma expressão de classificação embutida em código.
protected void ProductsDataSource_Selecting
(object sender, ObjectDataSourceSelectingEventArgs e)
{
// Have the ObjectDataSource sort the results by the selected
// sort expression
e.Arguments.SortExpression = SortBy.SelectedValue;
}
Neste ponto, ao visitar a página pela primeira vez, os produtos serão inicialmente classificados pelo ProductName
campo de dados, pois ele é o SortBy
ListItem
selecionado por padrão (consulte a Figura 6). Selecionar uma opção de classificação diferente, como Categoria e clicar em Atualizar, causará um postback e classificará novamente os dados pelo nome da categoria, como mostra a Figura 7.
Figura 6: Os produtos são inicialmente classificados pelo nome (clique para exibir a imagem em tamanho real)
Figura 7: Os produtos agora são classificados por categoria (clique para exibir a imagem em tamanho real)
Observação
Clicar no botão Atualizar faz com que os dados sejam automaticamente classificados novamente porque o estado de exibição do Repetidor foi desabilitado, fazendo com que o Repetidor seja reassociado à fonte de dados em cada postback. Se você deixou o estado de exibição do Repetidor habilitado, alterar a lista suspensa de classificação não terá nenhum efeito na ordem de classificação. Para corrigir isso, crie um manipulador de eventos para o evento do Click
Botão Atualizar e reassociar o Repetidor à fonte de dados (chamando o método Repeater s DataBind()
).
Lembrando a expressão de classificação e a direção
Ao criar um DataList ou Repeater classificável em uma página em que postbacks não relacionados à classificação podem ocorrer, é imperativo que a expressão de classificação e a direção sejam lembradas entre postbacks. Por exemplo, imagine que atualizamos o Repetidor neste tutorial para incluir um botão Excluir com cada produto. Quando o usuário clica no botão Excluir, executamos algum código para excluir o produto selecionado e, em seguida, reassociamos os dados ao Repetidor. Se os detalhes de classificação não forem persistidos no postback, os dados exibidos na tela reverter à ordem de classificação original.
Para este tutorial, o DropDownList salva implicitamente a expressão de classificação e a direção em seu estado de exibição para nós. Se estivéssemos usando uma interface de classificação diferente com, digamos, LinkButtons que forneceu as várias opções de classificação, precisaríamos ter cuidado para lembrar a ordem de classificação entre postbacks. Isso pode ser feito armazenando os parâmetros de classificação no estado de exibição da página, incluindo o parâmetro de classificação na querystring ou por meio de alguma outra técnica de persistência de estado.
Exemplos futuros neste tutorial exploram como persistir os detalhes de classificação no estado de exibição da página.
Etapa 5: Adicionar suporte de classificação a uma DataList que usa paginação padrão
No tutorial anterior , examinamos como implementar a paginação padrão com um DataList. Vamos estender este exemplo anterior para incluir a capacidade de classificar os dados paginado. Comece abrindo as SortingWithDefaultPaging.aspx
páginas e Paging.aspx
na PagingSortingDataListRepeater
pasta . Paging.aspx
Na página, clique no botão Origem para exibir a marcação declarativa da página. Copie o texto selecionado (consulte Figura 8) e cole-o na marcação declarativa entre SortingWithDefaultPaging.aspx
as <asp:Content>
marcas.
Figura 8: Replicar a Marcação Declarativa nas <asp:Content>
Marcas de Paging.aspx
para SortingWithDefaultPaging.aspx
(Clique para exibir a imagem em tamanho real)
Depois de copiar a marcação declarativa, copie os métodos e as propriedades na Paging.aspx
classe code-behind da página para a classe code-behind para SortingWithDefaultPaging.aspx
. Em seguida, reserve um momento para exibir a SortingWithDefaultPaging.aspx
página em um navegador. Ele deve exibir a mesma funcionalidade e aparência que Paging.aspx
.
Aprimorando productsBLL para incluir um método de paginação e classificação padrão
No tutorial anterior, criamos um GetProductsAsPagedDataSource(pageIndex, pageSize)
método na ProductsBLL
classe que retornava um PagedDataSource
objeto . Esse PagedDataSource
objeto foi preenchido com todos os produtos (por meio do método de SBLL GetProducts()
), mas quando associado à DataList apenas os registros correspondentes aos parâmetros de entrada pageIndex e pageSize especificados foram exibidos.
Anteriormente neste tutorial, adicionamos suporte à classificação especificando a expressão de classificação do manipulador de eventos ObjectDataSource Selecting
. Isso funciona bem quando ObjectDataSource é retornado um objeto que pode ser classificado, como o ProductsDataTable
retornado pelo GetProducts()
método . No entanto, o PagedDataSource
objeto retornado pelo GetProductsAsPagedDataSource
método não dá suporte à classificação de sua fonte de dados interna. Em vez disso, precisamos classificar os resultados retornados do GetProducts()
método antes de colocá-los no PagedDataSource
.
Para fazer isso, crie um novo método na ProductsBLL
classe . GetProductsSortedAsPagedDataSource(sortExpression, pageIndex, pageSize)
Para classificar o ProductsDataTable
retornado pelo GetProducts()
método , especifique a Sort
propriedade de seu padrão DataTableView
:
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, false)]
public PagedDataSource GetProductsSortedAsPagedDataSource
(string sortExpression, int pageIndex, int pageSize)
{
// Get ALL of the products
Northwind.ProductsDataTable products = GetProducts();
// Sort the products
products.DefaultView.Sort = sortExpression;
// Limit the results through a PagedDataSource
PagedDataSource pagedData = new PagedDataSource();
pagedData.DataSource = products.DefaultView;
pagedData.AllowPaging = true;
pagedData.CurrentPageIndex = pageIndex;
pagedData.PageSize = pageSize;
return pagedData;
}
O GetProductsSortedAsPagedDataSource
método difere apenas ligeiramente do GetProductsAsPagedDataSource
método criado no tutorial anterior. Em particular, GetProductsSortedAsPagedDataSource
aceita um parâmetro sortExpression
de entrada adicional e atribui esse valor à Sort
propriedade dos ProductDataTable
s DefaultView
. Algumas linhas de código posteriormente, o PagedDataSource
objeto DataSource recebe o ProductDataTable
s DefaultView
.
Chamando o método GetProductsSortedAsPagedDataSource e especificando o valor para o parâmetro de entrada SortExpression
Com o GetProductsSortedAsPagedDataSource
método concluído, a próxima etapa é fornecer o valor para esse parâmetro. O ObjectDataSource no SortingWithDefaultPaging.aspx
está atualmente configurado para chamar o GetProductsAsPagedDataSource
método e passa os dois parâmetros de entrada por meio de seus dois QueryStringParameters
, que são especificados na SelectParameters
coleção. Esses dois QueryStringParameters
indicam que a origem dos GetProductsAsPagedDataSource
parâmetros pageIndex e pageSize do método vêm dos campos pageIndex
querystring e pageSize
.
Atualize a propriedade ObjectDataSource para SelectMethod
que ele invoque o novo GetProductsSortedAsPagedDataSource
método. Em seguida, adicione um novo QueryStringParameter
para que o parâmetro de entrada sortExpression seja acessado do campo sortExpression
querystring . Defina os QueryStringParameter
s DefaultValue
como ProductName .
Após essas alterações, a marcação declarativa do ObjectDataSource deve ser semelhante a:
<asp:ObjectDataSource ID="ProductsDefaultPagingDataSource"
OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
SelectMethod="GetProductsSortedAsPagedDataSource"
OnSelected="ProductsDefaultPagingDataSource_Selected" runat="server">
<SelectParameters>
<asp:QueryStringParameter DefaultValue="ProductName"
Name="sortExpression" QueryStringField="sortExpression"
Type="String" />
<asp:QueryStringParameter DefaultValue="0" Name="pageIndex"
QueryStringField="pageIndex" Type="Int32" />
<asp:QueryStringParameter DefaultValue="4" Name="pageSize"
QueryStringField="pageSize" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
Neste ponto, a SortingWithDefaultPaging.aspx
página classificará seus resultados em ordem alfabética pelo nome do produto (consulte Figura 9). Isso ocorre porque, por padrão, um valor de ProductName é passado como o GetProductsSortedAsPagedDataSource
parâmetro sortExpression do método.
Figura 9: por padrão, os resultados são classificados por ProductName
(clique para exibir a imagem em tamanho real)
Se você adicionar manualmente um sortExpression
campo querystring, como SortingWithDefaultPaging.aspx?sortExpression=CategoryName
os resultados, será classificado pelo especificado sortExpression
. No entanto, esse sortExpression
parâmetro não é incluído na querystring ao mover para uma página de dados diferente. Na verdade, clicar nos botões Avançar ou Última página nos leva de volta para Paging.aspx
! Além disso, atualmente não há interface de classificação. A única maneira de um usuário alterar a ordem de classificação dos dados paginados é manipulando a querystring diretamente.
Criando a interface de classificação
Primeiro, precisamos atualizar o RedirectUser
método para enviar o usuário para SortingWithDefaultPaging.aspx
(em vez de Paging.aspx
) e incluir o sortExpression
valor na querystring. Também devemos adicionar uma propriedade nomeada SortExpression
no nível de página somente leitura. Essa propriedade, semelhante às PageIndex
propriedades e PageSize
criadas no tutorial anterior, retorna o valor do sortExpression
campo querystring se existir e o valor padrão ( ProductName ) caso contrário.
Atualmente, o RedirectUser
método aceita apenas um único parâmetro de entrada do índice da página a ser exibido. No entanto, pode haver momentos em que queremos redirecionar o usuário para uma página específica de dados usando uma expressão de classificação diferente da especificada na cadeia de caracteres de consulta. Em um momento, criaremos a interface de classificação para esta página, que incluirá uma série de controles Da Web de botão para classificar os dados por uma coluna especificada. Quando um desses Botões é clicado, queremos redirecionar o usuário passando o valor de expressão de classificação apropriado. Para fornecer essa funcionalidade, crie duas versões do RedirectUser
método . O primeiro deve aceitar apenas o índice de página a ser exibido, enquanto o segundo aceita o índice de página e a expressão de classificação.
private string SortExpression
{
get
{
if (!string.IsNullOrEmpty(Request.QueryString["sortExpression"]))
return Request.QueryString["sortExpression"];
else
return "ProductName";
}
}
private void RedirectUser(int sendUserToPageIndex)
{
// Use the SortExpression property to get the sort expression
// from the querystring
RedirectUser(sendUserToPageIndex, SortExpression);
}
private void RedirectUser(int sendUserToPageIndex, string sendUserSortingBy)
{
// Send the user to the requested page with the requested sort expression
Response.Redirect(string.Format(
"SortingWithDefaultPaging.aspx?pageIndex={0}&pageSize={1}&sortExpression={2}",
sendUserToPageIndex, PageSize, sendUserSortingBy));
}
No primeiro exemplo deste tutorial, criamos uma interface de classificação usando um DropDownList. Para este exemplo, vamos usar três controles Web de botão posicionados acima do DataList um para classificação por ProductName
, um para CategoryName
e outro para SupplierName
. Adicione os três controles Web button, definindo suas ID
propriedades e Text
adequadamente:
<p>
<asp:Button runat="server" id="SortByProductName"
Text="Sort by Product Name" />
<asp:Button runat="server" id="SortByCategoryName"
Text="Sort by Category" />
<asp:Button runat="server" id="SortBySupplierName"
Text="Sort by Supplier" />
</p>
Em seguida, crie um manipulador de eventos para cada um Click
. Os manipuladores de eventos devem chamar o RedirectUser
método , retornando o usuário para a primeira página usando a expressão de classificação apropriada.
protected void SortByProductName_Click(object sender, EventArgs e)
{
// Sort by ProductName
RedirectUser(0, "ProductName");
}
protected void SortByCategoryName_Click(object sender, EventArgs e)
{
// Sort by CategoryName
RedirectUser(0, "CategoryName");
}
protected void SortBySupplierName_Click(object sender, EventArgs e)
{
// Sort by SupplierName
RedirectUser(0, "SupplierName");
}
Ao visitar a página pela primeira vez, os dados são classificados pelo nome do produto em ordem alfabética (consulte a Figura 9). Clique no botão Avançar para avançar para a segunda página de dados e clique no botão Classificar por Categoria. Isso nos retorna à primeira página de dados, classificada pelo nome da categoria (consulte Figura 10). Da mesma forma, clicar no botão Classificar por Fornecedor classifica os dados por fornecedor a partir da primeira página de dados. A escolha de classificação é lembrada à medida que os dados são paginados. A Figura 11 mostra a página após a classificação por categoria e, em seguida, avança para a décima terceira página de dados.
Figura 10: Os produtos são classificados por categoria (clique para exibir a imagem em tamanho real)
Figura 11: a expressão de classificação é lembrada ao paginar os dados (clique para exibir a imagem em tamanho real)
Etapa 6: Paginação personalizada por meio de registros em um repetidor
O exemplo DataList examinado na etapa 5 páginas por meio de seus dados usando a técnica de paginação padrão ineficiente. Ao paginar quantidades suficientemente grandes de dados, é imperativo que a paginação personalizada seja usada. De volta aos tutoriais paginação eficiente por meio de grandes quantidades de dados e classificação de dados paginados personalizados , examinamos as diferenças entre a paginação padrão e personalizada e criamos métodos na BLL para utilizar paginação personalizada e classificar dados paginados personalizados. Em particular, nestes dois tutoriais anteriores, adicionamos os três métodos a ProductsBLL
seguir à classe :
GetProductsPaged(startRowIndex, maximumRows)
retorna um subconjunto específico de registros começando em startRowIndex e não excedendo maximumRows.GetProductsPagedAndSorted(sortExpression, startRowIndex, maximumRows)
retorna um subconjunto específico de registros classificados pelo parâmetro de entrada sortExpression especificado.TotalNumberOfProducts()
fornece o número total de registros na tabela deProducts
banco de dados.
Esses métodos podem ser usados para paginar e classificar com eficiência os dados usando um controle DataList ou Repeater. Para ilustrar isso, vamos começar criando um controle Repeater com suporte à paginação personalizada; Em seguida, adicionaremos recursos de classificação.
Abra a SortingWithCustomPaging.aspx
página na PagingSortingDataListRepeater
pasta e adicione um Repetidor à página, definindo sua ID
propriedade como Products
. Na marca inteligente repeater, crie um novo ObjectDataSource chamado ProductsDataSource
. Configure-o para selecionar seus dados no ProductsBLL
método da classe s GetProductsPaged
.
Figura 12: configurar o ObjectDataSource para usar o ProductsBLL
método da GetProductsPaged
classe (clique para exibir a imagem em tamanho real)
Defina as listas suspensas nas guias UPDATE, INSERT e DELETE como (Nenhum) e clique no botão Avançar. O assistente Configurar Fonte de Dados agora solicita as fontes dos parâmetros de GetProductsPaged
entrada startRowIndex e maximumRows do método. Na realidade, esses parâmetros de entrada são ignorados. Em vez disso, os valores startRowIndex e maximumRows serão passados por meio da Arguments
propriedade no manipulador de eventos ObjectDataSource Selecting
, assim como especificamos a sortExpression na primeira demonstração deste tutorial. Portanto, deixe as listas suspensas de origem do parâmetro no conjunto de assistentes em Nenhum .
Figura 13: deixe as fontes de parâmetro definidas como nenhuma (clique para exibir a imagem em tamanho real)
Observação
Não defina a propriedade true
ObjectDataSource como EnablePaging
. Isso fará com que ObjectDataSource inclua automaticamente seus próprios parâmetros startRowIndex e maximumRows para a SelectMethod
lista de parâmetros existente. A EnablePaging
propriedade é útil ao associar dados paginados personalizados a um controle GridView, DetailsView ou FormView porque esses controles esperam determinado comportamento do ObjectDataSource que só está disponível quando EnablePaging
a propriedade é true
. Como temos que adicionar manualmente o suporte de paginação para DataList e Repeater, deixe essa propriedade definida false
como (o padrão), pois assaremos na funcionalidade necessária diretamente em nossa página de ASP.NET.
Por fim, defina os Repeater s ItemTemplate
para que o nome, a categoria e o fornecedor do produto sejam mostrados. Após essas alterações, a sintaxe declarativa de Repeater e ObjectDataSource deve ser semelhante à seguinte:
<asp:Repeater ID="Products" runat="server" DataSourceID="ProductsDataSource"
EnableViewState="False">
<ItemTemplate>
<h4><asp:Label ID="ProductNameLabel" runat="server"
Text='<%# Eval("ProductName") %>'></asp:Label></h4>
Category:
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Eval("CategoryName") %>'></asp:Label><br />
Supplier:
<asp:Label ID="SupplierNameLabel" runat="server"
Text='<%# Eval("SupplierName") %>'></asp:Label><br />
<br />
<br />
</ItemTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProductsPaged" TypeName="ProductsBLL">
<SelectParameters>
<asp:Parameter Name="startRowIndex" Type="Int32" />
<asp:Parameter Name="maximumRows" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
Reserve um momento para visitar a página por meio de um navegador e observe que nenhum registro é retornado. Isso ocorre porque ainda não especificamos os valores de parâmetro startRowIndex e maximumRows ; portanto, os valores de 0 estão sendo passados para ambos. Para especificar esses valores, crie um manipulador de eventos para o evento ObjectDataSource Selecting
e defina esses valores de parâmetros programaticamente como valores embutidos em código de 0 e 5, respectivamente:
protected void ProductsDataSource_Selecting
(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.InputParameters["startRowIndex"] = 0;
e.InputParameters["maximumRows"] = 5;
}
Com essa alteração, a página, quando exibida por meio de um navegador, mostra os cinco primeiros produtos.
Figura 14: Os cinco primeiros registros são exibidos (clique para exibir a imagem em tamanho real)
Observação
Os produtos listados na Figura 14 são classificados pelo nome do produto porque o GetProductsPaged
procedimento armazenado que executa a consulta de paginação personalizada eficiente ordena os resultados por ProductName
.
Para permitir que o usuário percorra as páginas, precisamos acompanhar o índice de linha inicial e as linhas máximas e lembrar esses valores entre postbacks. No exemplo de paginação padrão, usamos campos querystring para persistir esses valores; para essa demonstração, vamos persistir essas informações no estado de exibição da página. Crie as duas propriedades a seguir:
private int StartRowIndex
{
get
{
object o = ViewState["StartRowIndex"];
if (o == null)
return 0;
else
return (int)o;
}
set
{
ViewState["StartRowIndex"] = value;
}
}
private int MaximumRows
{
get
{
object o = ViewState["MaximumRows"];
if (o == null)
return 5;
else
return (int)o;
}
set
{
ViewState["MaximumRows"] = value;
}
}
Em seguida, atualize o código no manipulador de eventos Selecting para que ele use as StartRowIndex
propriedades e MaximumRows
em vez dos valores embutidos em código de 0 e 5:
e.InputParameters["startRowIndex"] = StartRowIndex;
e.InputParameters["maximumRows"] = MaximumRows;
Neste ponto, nossa página ainda mostra apenas os cinco primeiros registros. No entanto, com essas propriedades em vigor, estamos prontos para criar nossa interface de paginação.
Adicionando a interface de paginação
Vamos usar a mesma interface de paginação First, Previous, Next, Last usada no exemplo de paginação padrão, incluindo o controle Web Rótulo que exibe qual página de dados está sendo exibida e quantas páginas totais existem. Adicione os quatro controles Da Web de Botão e Rótulo abaixo do Repetidor.
<p>
<asp:Button runat="server" ID="FirstPage" Text="<< First" />
<asp:Button runat="server" ID="PrevPage" Text="< Prev" />
<asp:Button runat="server" ID="NextPage" Text="Next >" />
<asp:Button runat="server" ID="LastPage" Text="Last >>" />
</p>
<p>
<asp:Label runat="server" ID="CurrentPageNumber"></asp:Label>
</p>
Em seguida, crie Click
manipuladores de eventos para os quatro Botões. Quando um desses Botões é clicado, precisamos atualizar o StartRowIndex
e reassociar os dados ao Repetidor. O código para os botões Primeiro, Anterior e Próximo é simples o suficiente, mas para o botão Último, como determinamos o índice de linha inicial da última página de dados? Para calcular esse índice, além de poder determinar se os botões Avançar e Último devem ser habilitados, precisamos saber quantos registros no total estão sendo paginados. Podemos determinar isso chamando o ProductsBLL
método da classe s TotalNumberOfProducts()
. Vamos criar uma propriedade de nível de página somente leitura chamada TotalRowCount
que retorna os resultados do TotalNumberOfProducts()
método :
private int TotalRowCount
{
get
{
// Return the value from the TotalNumberOfProducts() method
ProductsBLL productsAPI = new ProductsBLL();
return productsAPI.TotalNumberOfProducts();
}
}
Com essa propriedade, agora podemos determinar o índice de linha inicial da última página. Especificamente, é o resultado inteiro do TotalRowCount
menos 1 dividido por MaximumRows
, multiplicado por MaximumRows
. Agora podemos escrever os Click
manipuladores de eventos para os quatro botões de interface de paginação:
protected void FirstPage_Click(object sender, EventArgs e)
{
// Return to StartRowIndex of 0 and rebind data
StartRowIndex = 0;
Products.DataBind();
}
protected void PrevPage_Click(object sender, EventArgs e)
{
// Subtract MaximumRows from StartRowIndex and rebind data
StartRowIndex -= MaximumRows;
Products.DataBind();
}
protected void NextPage_Click(object sender, EventArgs e)
{
// Add MaximumRows to StartRowIndex and rebind data
StartRowIndex += MaximumRows;
Products.DataBind();
}
protected void LastPage_Click(object sender, EventArgs e)
{
// Set StartRowIndex = to last page's starting row index and rebind data
StartRowIndex = ((TotalRowCount - 1) / MaximumRows) * MaximumRows;
Products.DataBind();
}
Por fim, precisamos desabilitar os botões Primeiro e Anterior na interface de paginação ao exibir a primeira página de dados e os botões Avançar e Último ao exibir a última página. Para fazer isso, adicione o seguinte código ao manipulador de eventos ObjectDataSource Selecting
:
// Disable the paging interface buttons, if needed
FirstPage.Enabled = StartRowIndex != 0;
PrevPage.Enabled = StartRowIndex != 0;
int LastPageStartRowIndex = ((TotalRowCount - 1) / MaximumRows) * MaximumRows;
NextPage.Enabled = StartRowIndex < LastPageStartRowIndex;
LastPage.Enabled = StartRowIndex < LastPageStartRowIndex;
Depois de adicionar esses Click
manipuladores de eventos e o código para habilitar ou desabilitar os elementos da interface de paginação com base no índice de linha inicial atual, teste a página em um navegador. Como ilustra a Figura 15, ao visitar pela primeira vez a página, os botões Primeiro e Anterior serão desabilitados. Clicar em Avançar mostra a segunda página de dados, enquanto clicar em Último exibe a página final (consulte Figuras 16 e 17). Ao exibir a última página de dados, os botões Avançar e Último são desabilitados.
Figura 15: Os botões Anterior e Último são desabilitados ao exibir a primeira página de produtos (clique para exibir a imagem em tamanho real)
Figura 16: a segunda página de produtos é exibida (clique para exibir a imagem em tamanho real)
Figura 17: Clicar em Último exibe a página final de dados (clique para exibir a imagem em tamanho real)
Etapa 7: Incluindo o suporte à classificação com o repetidor de páginas personalizado
Agora que a paginação personalizada foi implementada, estamos prontos para incluir o suporte de classificação. O ProductsBLL
método de classe s GetProductsPagedAndSorted
tem os mesmos parâmetros de entrada startRowIndex e maximumRows que GetProductsPaged
, mas permite um parâmetro de entrada sortExpression adicional. Para usar o GetProductsPagedAndSorted
método de SortingWithCustomPaging.aspx
, precisamos executar as seguintes etapas:
- Altere a propriedade
GetProductsPaged
ObjectDataSource deSelectMethod
paraGetProductsPagedAndSorted
. - Adicione um objeto sortExpression
Parameter
à coleção ObjectDataSourceSelectParameters
. - Crie uma propriedade privada no nível
SortExpression
da página que persista seu valor entre postbacks por meio do estado de exibição da página. - Atualize o manipulador de eventos objectDataSource
Selecting
para atribuir ao parâmetro sortExpression do ObjectDataSource o valor da propriedade no nívelSortExpression
da página. - Crie a interface de classificação.
Comece atualizando a propriedade ObjectDataSource e SelectMethod
adicionando uma sortExpressionParameter
. Verifique se a propriedade sortExpressionParameter
s Type
está definida como String
. Depois de concluir essas duas primeiras tarefas, a marcação declarativa do ObjectDataSource deve ser semelhante à seguinte:
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}" TypeName="ProductsBLL"
SelectMethod="GetProductsPagedAndSorted"
OnSelecting="ProductsDataSource_Selecting">
<SelectParameters>
<asp:Parameter Name="sortExpression" Type="String" />
<asp:Parameter Name="startRowIndex" Type="Int32" />
<asp:Parameter Name="maximumRows" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
Em seguida, precisamos de uma propriedade no nível SortExpression
da página cujo valor é serializado para exibir o estado. Se nenhum valor de expressão de classificação tiver sido definido, use ProductName como o padrão:
private string SortExpression
{
get
{
object o = ViewState["SortExpression"];
if (o == null)
return "ProductName";
else
return o.ToString();
}
set
{
ViewState["SortExpression"] = value;
}
}
Antes que ObjectDataSource invoque o GetProductsPagedAndSorted
método, precisamos definir sortExpressionParameter
para o valor da SortExpression
propriedade . Selecting
No manipulador de eventos, adicione a seguinte linha de código:
e.InputParameters["sortExpression"] = SortExpression;
Tudo o que resta é implementar a interface de classificação. Como fizemos no último exemplo, vamos ter a interface de classificação implementada usando três controles Da Web de botão que permitem que o usuário classifique os resultados por nome do produto, categoria ou fornecedor.
<asp:Button runat="server" id="SortByProductName"
Text="Sort by Product Name" />
<asp:Button runat="server" id="SortByCategoryName"
Text="Sort by Category" />
<asp:Button runat="server" id="SortBySupplierName"
Text="Sort by Supplier" />
Crie Click
manipuladores de eventos para esses três controles Button. No manipulador de eventos, redefina para StartRowIndex
0, defina o SortExpression
como o valor apropriado e rebine os dados para o Repetidor:
protected void SortByProductName_Click(object sender, EventArgs e)
{
StartRowIndex = 0;
SortExpression = "ProductName";
Products.DataBind();
}
protected void SortByCategoryName_Click(object sender, EventArgs e)
{
StartRowIndex = 0;
SortExpression = "CategoryName";
Products.DataBind();
}
protected void SortBySupplierName_Click(object sender, EventArgs e)
{
StartRowIndex = 0;
SortExpression = "CompanyName";
Products.DataBind();
}
Isso é tudo o que há para ele! Embora houvesse várias etapas para implementar a paginação e a classificação personalizadas, as etapas eram muito semelhantes às necessárias para paginação padrão. A Figura 18 mostra os produtos ao exibir a última página de dados quando classificada por categoria.
Figura 18: a última página de dados, classificada por categoria, é exibida (Clique para exibir a imagem em tamanho real)
Observação
Em exemplos anteriores, ao classificar pelo fornecedor SupplierName era usado como a expressão de classificação. No entanto, para a implementação de paginação personalizada, precisamos usar CompanyName. Isso ocorre porque o procedimento armazenado responsável por implementar a paginação GetProductsPagedAndSorted
personalizada passa a expressão de classificação para o ROW_NUMBER()
palavra-chave, o ROW_NUMBER()
palavra-chave requer o nome da coluna real em vez de um alias. Portanto, devemos usar CompanyName
(o nome da coluna na tabela) em Suppliers
vez do alias usado na SELECT
consulta (SupplierName
) para a expressão de classificação.
Resumo
Nem o DataList nem o Repeater oferecem suporte de classificação interno, mas com um pouco de código e uma interface de classificação personalizada, essa funcionalidade pode ser adicionada. Ao implementar a classificação, mas não a paginação, a expressão de classificação pode ser especificada por meio do DataSourceSelectArguments
objeto passado para o método ObjectDataSource.Select
Essa DataSourceSelectArguments
propriedade do SortExpression
objeto pode ser atribuída no manipulador de eventos ObjectDataSource Selecting
.
Para adicionar recursos de classificação a um DataList ou Repeater que já fornece suporte à paginação, a abordagem mais fácil é personalizar a Camada lógica de negócios para incluir um método que aceita uma expressão de classificação. Essas informações podem ser passadas por meio de um parâmetro no ObjectDataSource s SelectParameters
.
Este tutorial conclui nosso exame de paginação e classificação com os controles DataList e Repeater. Nosso próximo e último tutorial examinará como adicionar controles Web de botão aos modelos DataList e Repeater para fornecer alguma funcionalidade personalizada iniciada pelo usuário por item.
Programação feliz!
Sobre o autor
Scott Mitchell, autor de sete livros do ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Microsoft Web desde 1998. Scott trabalha como consultor independente, treinador e escritor. Seu último livro é Sams Teach Yourself ASP.NET 2.0 em 24 Horas. Ele pode ser contatado em mitchell@4GuysFromRolla.com. ou através de seu blog, que pode ser encontrado em http://ScottOnWriting.NET.
Agradecimentos Especiais
Esta série de tutoriais foi revisada por muitos revisores úteis. O revisor principal deste tutorial foi David Suru. Interessado em revisar meus próximos artigos do MSDN? Nesse caso, solte-me uma linha em mitchell@4GuysFromRolla.com.
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de