Condividi tramite


Ordinamento dei dati in un controllo DataList o Repeater (C#)

di Scott Mitchell

Scarica il PDF

In questa esercitazione verrà illustrato come includere il supporto per l'ordinamento in DataList e Repeater, nonché come costruire un DataList o Repeater i cui dati possono essere visualizzati e ordinati.

Introduzione

Nell'esercitazione precedente è stato esaminato come aggiungere il supporto per il paging a un oggetto DataList. È stato creato un nuovo metodo nella ProductsBLL classe (GetProductsAsPagedDataSource) che ha restituito un PagedDataSource oggetto. Se associato a un oggetto DataList o Repeater, DataList o Repeater visualizzerebbe solo la pagina richiesta di dati. Questa tecnica è simile a quella usata internamente dai controlli GridView, DetailsView e FormView per fornire la funzionalità predefinita di paging predefinita.

Oltre all'offerta di supporto per il paging, GridView include anche il supporto per l'ordinamento automatico. Né DataList né Repeater offrono funzionalità di ordinamento predefinite; Tuttavia, è possibile aggiungere funzionalità di ordinamento con un bit di codice. In questa esercitazione verrà illustrato come includere il supporto per l'ordinamento in DataList e Repeater, nonché come costruire un DataList o Repeater i cui dati possono essere visualizzati e ordinati.

Revisione dell'ordinamento

Come illustrato nell'esercitazione Paging e ordinamento dei dati del report , il controllo GridView fornisce il supporto per l'ordinamento delle caselle. Ogni campo GridView può avere un oggetto associato SortExpression, che indica il campo dati in base al quale ordinare i dati. Quando la proprietà GridView s AllowSorting è impostata su true, ogni campo GridView con un SortExpression valore di proprietà ha il rendering dell'intestazione come LinkButton. Quando un utente fa clic su un'intestazione di un determinato campo GridView, si verifica un postback e i dati vengono ordinati in base al campo fatto clic.SortExpression

Il controllo GridView ha anche una SortExpression proprietà che archivia il campo GridView per cui SortExpression i dati vengono ordinati. Inoltre, una SortDirection proprietà indica se i dati devono essere ordinati in ordine crescente o decrescente (se un utente fa clic su un particolare collegamento di intestazione del campo GridView due volte in successione, l'ordine di ordinamento viene disattivato).

Quando GridView è associato al controllo origine dati, disattiva le SortExpression relative proprietà e SortDirection al controllo origine dati. Il controllo origine dati recupera i dati e quindi lo ordina in base alle proprietà e SortDirection forniteSortExpression. Dopo l'ordinamento dei dati, il controllo origine dati lo restituisce a GridView.

Per replicare questa funzionalità con i controlli DataList o Repeater, è necessario:

  • Creare un'interfaccia di ordinamento
  • Tenere presente che il campo dati è in grado di ordinare in base a e se ordinare in ordine crescente o decrescente
  • Indicare a ObjectDataSource di ordinare i dati in base a un determinato campo dati

Verranno affrontate queste tre attività nei passaggi 3 e 4. In seguito, si esaminerà come includere sia il paging che il supporto per l'ordinamento in un oggetto DataList o Repeater.

Passaggio 2: Visualizzazione dei prodotti in un ripetitore

Prima di preoccuparsi di implementare una delle funzionalità correlate all'ordinamento, iniziare elencando i prodotti in un controllo Repeater. Iniziare aprendo la Sorting.aspx pagina nella PagingSortingDataListRepeater cartella. Aggiungere un controllo Repeater alla pagina Web, impostandone la ID proprietà su SortableProducts. Dallo smart tag repeater creare un nuovo oggetto ObjectDataSource denominato ProductsDataSource e configurarlo per recuperare i dati dal ProductsBLL metodo della GetProducts() classe. Selezionare l'opzione (Nessuna) negli elenchi a discesa nelle schede INSERT, UPDATE e DELETE.

Creare un oggetto ObjectDataSource e configurarlo per usare il metodo GetProductsAsPagedDataSource()

Figura 1: Creare un oggetto ObjectDataSource e configurarlo per usare il metodo (fare clic per visualizzare l'immagineGetProductsAsPagedDataSource() a dimensioni complete)

Impostare la Drop-Down Elenchi nelle schede UPDATE, INSERT e DELETE su (Nessuno)

Figura 2: Impostare la Drop-Down Elenchi nelle schede UPDATE, INSERT e DELETE su (Nessuno) (Fare clic per visualizzare l'immagine full-size)

A differenza di DataList, Visual Studio non crea automaticamente un ItemTemplate oggetto per il controllo Repeater dopo l'associazione a un'origine dati. Inoltre, è necessario aggiungere questa ItemTemplate opzione dichiarativamente, poiché lo smart tag del ripetitore non ha l'opzione Modifica modelli trovata in DataList s. Consente di usare lo stesso ItemTemplate dell'esercitazione precedente, che ha visualizzato il nome, il fornitore e la categoria del prodotto.

Dopo aver aggiunto , ItemTemplateil markup dichiarativo ripetitore e ObjectDataSource deve essere simile al seguente:

<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>

La figura 3 mostra questa pagina quando visualizzata tramite un browser.

Ogni nome, fornitore e categoria del prodotto viene visualizzato

Figura 3: Ogni nome, fornitore e categoria del prodotto viene visualizzato (fare clic per visualizzare l'immagine full-size)

Passaggio 3: Indicare a ObjectDataSource di ordinare i dati

Per ordinare i dati visualizzati nel ripetitore, è necessario informare ObjectDataSource dell'espressione di ordinamento in base alla quale devono essere ordinati i dati. Prima che ObjectDataSource recupera i dati, viene generato Selectingprima di tutto l'evento, che offre l'opportunità di specificare un'espressione di ordinamento. Il Selecting gestore eventi viene passato un oggetto di tipo ObjectDataSourceSelectingEventArgs, che ha una proprietà denominata Arguments di tipo DataSourceSelectArguments. La DataSourceSelectArguments classe è progettata per passare richieste correlate ai dati da un consumer di dati al controllo origine dati e include una SortExpression proprietà.

Per passare le informazioni di ordinamento dalla pagina ASP.NET a ObjectDataSource, creare un gestore eventi per l'evento Selecting e usare il codice seguente:

protected void ProductsDataSource_Selecting
    (object sender, ObjectDataSourceSelectingEventArgs e)
{
    e.Arguments.SortExpression = sortExpression;
}

Il valore sortExpression deve essere assegnato al nome del campo dati per ordinare i dati in base (ad esempio ProductName). Non esiste alcuna proprietà relativa alla direzione di ordinamento, quindi se si desidera ordinare i dati in ordine decrescente, aggiungere la stringa DESC al valore sortExpression (ad esempio ProductName DESC).

Andare avanti e provare alcuni valori hardcoded diversi per sortExpression e testare i risultati in un browser. Come illustrato nella figura 4, quando si usa ProductName DESC come sortExpression, i prodotti vengono ordinati in base al nome in ordine alfabetico inverso.

I prodotti vengono ordinati in base al nome in Ordine alfabetico inverso

Figura 4: i prodotti vengono ordinati in base al nome nell'ordine alfabetico inverso (fare clic per visualizzare l'immagine full-size)

Passaggio 4: Creazione dell'interfaccia di ordinamento e memorizzazione dell'espressione di ordinamento e direzione

L'attivazione del supporto per l'ordinamento in GridView converte il testo dell'intestazione di ogni campo ordinabile in un linkButton che, quando viene fatto clic, ordina di conseguenza i dati. Tale interfaccia di ordinamento ha senso per GridView, in cui i dati sono ben disposti nelle colonne. Per i controlli DataList e Repeater, tuttavia, è necessaria un'interfaccia di ordinamento diversa. Un'interfaccia di ordinamento comune per un elenco di dati (anziché una griglia di dati), è un elenco a discesa che fornisce i campi in base ai quali è possibile ordinare i dati. Implementare tale interfaccia per questa esercitazione.

Aggiungere un controllo Web DropDownList sopra il SortableProducts ripetitore e impostarne la ID proprietà su SortBy. Nella Finestra Proprietà fare clic sui puntini di sospensione nella Items proprietà per visualizzare l'Editor dell'insieme ListItem. Aggiungere ListItem s per ordinare i dati in base ProductNameai campi , CategoryNamee SupplierName . Aggiungere anche un ListItem oggetto per ordinare i prodotti in base al nome in ordine alfabetico inverso.

Le ListItemText proprietà possono essere impostate su qualsiasi valore ( ad esempio Name ), ma le Value proprietà devono essere impostate sul nome del campo dati ( ad esempio ProductName ). Per ordinare i risultati in ordine decrescente, aggiungere la stringa DESC al nome del campo dati, ad esempio ProductName DESC .

Aggiungere un oggetto ListItem per ognuno dei campi dati ordinabili

Figura 5: Aggiungere un oggetto ListItem per ognuno dei campi dati ordinabili

Infine, aggiungere un controllo Web Button a destra di DropDownList. ID Impostare su RefreshRepeater e sulla relativa Text proprietà su Aggiorna .

Dopo aver creato lo ListItem s e aggiunto il pulsante Aggiorna, la sintassi dichiarativa DropDownList e Button deve essere simile alla seguente:

<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" />

Con il completamento dell'ordinamento DropDownList, è necessario aggiornare il gestore eventi objectDataSource s in modo che usi la proprietà s SelectingValue selezionata SortBy``ListItem anziché un'espressione di ordinamento hardcoded.

protected void ProductsDataSource_Selecting
    (object sender, ObjectDataSourceSelectingEventArgs e)
{
    // Have the ObjectDataSource sort the results by the selected
    // sort expression
    e.Arguments.SortExpression = SortBy.SelectedValue;
}

A questo punto, quando si visita la pagina i prodotti verranno inizialmente ordinati per il ProductName campo dati, come viene selezionato per impostazione predefinita (vedere la SortByListItem figura 6). Selezionando un'opzione di ordinamento diversa, ad esempio Categoria e facendo clic su Aggiorna, verrà generato un postback e riordinare i dati in base al nome della categoria, come illustrato nella figura 7.

I prodotti vengono inizialmente ordinati in base al nome

Figura 6: I prodotti vengono inizialmente ordinati in base al nome (fare clic per visualizzare l'immagine full-size)

I prodotti sono ora ordinati in base alla categoria

Figura 7: I prodotti sono ora ordinati per categoria (fare clic per visualizzare l'immagine a dimensioni complete)

Nota

Facendo clic sul pulsante Aggiorna, i dati devono essere riordinati automaticamente perché lo stato di visualizzazione del ripetitore è stato disabilitato, causando la ribinazione del ripetitore all'origine dati in ogni postback. Se è stato abilitato lo stato di visualizzazione del ripetitore, la modifica dell'elenco a discesa dell'ordinamento non avrà alcun effetto sull'ordine di ordinamento. Per risolvere questo problema, creare un gestore eventi per l'evento Refresh Button s Click e ribinare il ripetitore all'origine dati (chiamando il metodo Repeater).DataBind()

Ricordare l'espressione di ordinamento e la direzione

Quando si crea un oggetto DataList o Repeater ordinabile in una pagina in cui possono verificarsi postback non correlati all'ordinamento, è imperativo ricordare l'espressione di ordinamento e la direzione tra postback. Si supponga, ad esempio, di aver aggiornato il ripetitore in questa esercitazione per includere un pulsante Elimina con ogni prodotto. Quando l'utente fa clic sul pulsante Elimina viene eseguito un codice per eliminare il prodotto selezionato e quindi ribinare i dati nel ripetitore. Se i dettagli dell'ordinamento non vengono mantenuti nel postback, i dati visualizzati sullo schermo verranno ripristinati nell'ordine di ordinamento originale.

Per questa esercitazione, DropDownList salva in modo implicito l'espressione di ordinamento e la direzione nello stato di visualizzazione. Se si usa un'interfaccia di ordinamento diversa con, ad esempio LinkButtons che ha fornito le varie opzioni di ordinamento, è necessario tenere presente l'ordine di ordinamento tra postback. Questa operazione può essere eseguita archiviando i parametri di ordinamento nello stato di visualizzazione della pagina, includendo il parametro di ordinamento nella querystring o tramite alcune altre tecniche di persistenza dello stato.

Gli esempi futuri in questa esercitazione illustrano come rendere persistenti i dettagli di ordinamento nello stato di visualizzazione della pagina.

Passaggio 5: Aggiunta del supporto di ordinamento a un elenco di dati che usa il paging predefinito

Nell'esercitazione precedente è stato illustrato come implementare il paging predefinito con un oggetto DataList. Estendere questo esempio precedente per includere la possibilità di ordinare i dati paginati. Iniziare aprendo le SortingWithDefaultPaging.aspx pagine e Paging.aspx nella PagingSortingDataListRepeater cartella. Paging.aspx Nella pagina fare clic sul pulsante Origine per visualizzare il markup dichiarativo della pagina. Copiare il testo selezionato (vedere la figura 8) e incollarlo nel markup dichiarativo dei SortingWithDefaultPaging.aspx<asp:Content> tag.

Replicare il markup dichiarativo in <asp:Content> Tags da Paging.aspx a SortingWithDefaultPaging.aspx

Figura 8: Replicare il markup dichiarativo nei <asp:Content> tag da Paging.aspx a SortingWithDefaultPaging.aspx (fare clic per visualizzare l'immagine a dimensioni complete)

Dopo aver copiato il markup dichiarativo, copiare i metodi e le proprietà nella classe code-behind della Paging.aspx pagina nella classe code-behind per SortingWithDefaultPaging.aspx. Quindi, per visualizzare la SortingWithDefaultPaging.aspx pagina in un browser, prendere un momento. Deve presentare la stessa funzionalità e aspetto di Paging.aspx.

Miglioramento di ProductsBLL per includere un metodo di paging e ordinamento predefinito

Nell'esercitazione precedente è stato creato un GetProductsAsPagedDataSource(pageIndex, pageSize) metodo nella ProductsBLL classe che ha restituito un PagedDataSource oggetto. Questo PagedDataSource oggetto è stato popolato con tutti i prodotti (tramite il metodo BLL), GetProducts() ma quando associato a DataList sono stati visualizzati solo i record corrispondenti ai parametri di input pageIndex e pageSize specificati.

In precedenza in questa esercitazione è stato aggiunto il supporto per l'ordinamento specificando l'espressione di ordinamento dal gestore eventi di ObjectDataSource.Selecting Questa operazione funziona correttamente quando objectDataSource viene restituito un oggetto che può essere ordinato, ad esempio il ProductsDataTable restituito dal GetProducts() metodo . Tuttavia, l'oggetto restituito dal metodo non supporta l'ordinamento dell'origine PagedDataSourceGetProductsAsPagedDataSource dati interna. È invece necessario ordinare i risultati restituiti dal GetProducts() metodo prima di inserirli in PagedDataSource.

A tale scopo, creare un nuovo metodo nella ProductsBLL classe , GetProductsSortedAsPagedDataSource(sortExpression, pageIndex, pageSize). Per ordinare il ProductsDataTable restituito dal GetProducts() metodo, specificare la Sort proprietà del valore predefinito 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;
}

Il GetProductsSortedAsPagedDataSource metodo differisce leggermente dal GetProductsAsPagedDataSource metodo creato nell'esercitazione precedente. In particolare, GetProductsSortedAsPagedDataSource accetta un parametro sortExpression di input aggiuntivo e assegna questo valore alla Sort proprietà di ProductDataTable s DefaultView. In seguito vengono assegnate alcune righe di codice all'oggetto PagedDataSource DataSource.ProductDataTableDefaultView

Chiamata al metodo GetProductsSortedAsPagedDataSource e specificare il valore per il parametro di input SortExpression

Al termine del metodo, il GetProductsSortedAsPagedDataSource passaggio successivo consiste nel fornire il valore per questo parametro. ObjectDataSource in SortingWithDefaultPaging.aspx è attualmente configurato per chiamare il GetProductsAsPagedDataSource metodo e passa i due parametri di input tramite i due QueryStringParameters, specificati nella SelectParameters raccolta. Questi due QueryStringParameters indicano che l'origine per i GetProductsAsPagedDataSource parametri pageIndex e pageSize del metodo provengono dai campi pageIndex querystring e pageSize.

Aggiornare la proprietà ObjectDataSource in SelectMethod modo che richiama il nuovo GetProductsSortedAsPagedDataSource metodo. Aggiungere quindi un nuovo QueryStringParameter oggetto in modo che il parametro di input sortExpression sia accessibile dal campo sortExpressionquerystring . Impostare s QueryStringParameterDefaultValue su ProductName .

Dopo queste modifiche, il markup dichiarativo di ObjectDataSource deve essere simile al seguente:

<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>

A questo punto, la SortingWithDefaultPaging.aspx pagina ordina i risultati in ordine alfabetico in base al nome del prodotto (vedere la figura 9). Questo perché, per impostazione predefinita, viene passato un valore di ProductName come parametro sortExpression del GetProductsSortedAsPagedDataSource metodo.

Per impostazione predefinita, i risultati vengono ordinati in base a ProductName

Figura 9: Per impostazione predefinita, i risultati vengono ordinati per ProductName (Fare clic per visualizzare l'immagine a dimensioni complete)

Se si aggiunge manualmente un sortExpression campo querystring, SortingWithDefaultPaging.aspx?sortExpression=CategoryName ad esempio i risultati, verranno ordinati in base all'oggetto specificato sortExpression. Tuttavia, questo sortExpression parametro non è incluso nella querystring quando si passa a una pagina diversa di dati. In effetti, facendo clic sui pulsanti Avanti o Ultima pagina ci riporta a Paging.aspx! Inoltre, non esiste attualmente alcuna interfaccia di ordinamento. L'unico modo in cui un utente può modificare l'ordine di ordinamento dei dati di pagina è modificando direttamente la querystring.

Creazione dell'interfaccia di ordinamento

Per prima cosa è necessario aggiornare il RedirectUser metodo per inviare l'utente a SortingWithDefaultPaging.aspx (anziché Paging.aspx) e per includere il sortExpression valore nella querystring. È anche necessario aggiungere una proprietà denominata SortExpression a livello di pagina di sola lettura. Questa proprietà, simile alle PageIndex proprietà e PageSize create nell'esercitazione precedente, restituisce il valore del sortExpression campo querystring se esiste e il valore predefinito ( ProductName ) in caso contrario.

Attualmente il RedirectUser metodo accetta solo un singolo parametro di input per visualizzare l'indice della pagina. Tuttavia, potrebbe verificarsi un momento in cui si vuole reindirizzare l'utente a una determinata pagina di dati usando un'espressione di ordinamento diversa da quella specificata nella querystring. In un momento verrà creata l'interfaccia di ordinamento per questa pagina, che includerà una serie di controlli Web Button per ordinare i dati in base a una colonna specificata. Quando si fa clic su uno di questi pulsanti, si vuole reindirizzare l'utente passando il valore dell'espressione di ordinamento appropriato. Per fornire questa funzionalità, creare due versioni del RedirectUser metodo. Il primo deve accettare solo l'indice di pagina da visualizzare, mentre il secondo accetta l'indice della pagina e l'espressione di ordinamento.

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));
}

Nel primo esempio di questa esercitazione è stata creata un'interfaccia di ordinamento usando un elenco a discesa. Per questo esempio, è possibile usare tre controlli Web Button posizionati sopra l'elenco dati uno per l'ordinamento per ProductName, uno per CategoryNamee uno per SupplierName. Aggiungere i tre controlli Web Button, impostandone ID le proprietà e Text in modo appropriato:

<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>

Creare quindi un Click gestore eventi per ognuno. I gestori eventi devono chiamare il RedirectUser metodo, restituendo l'utente alla prima pagina usando l'espressione di ordinamento appropriata.

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");
}

Quando si visita per la prima volta la pagina, i dati vengono ordinati in base al nome del prodotto in ordine alfabetico (fare riferimento alla figura 9). Fare clic sul pulsante Avanti per passare alla seconda pagina di dati e quindi fare clic sul pulsante Ordina per categoria. In questo modo viene restituita la prima pagina dei dati, ordinata in base al nome della categoria (vedere la figura 10). Analogamente, fare clic sul pulsante Ordina per fornitore ordina i dati in base al fornitore a partire dalla prima pagina dei dati. La scelta di ordinamento viene ricordata come i dati vengono inseriti in pagina. La figura 11 mostra la pagina dopo l'ordinamento in base alla categoria e quindi passa alla tredicesima pagina dei dati.

I prodotti sono ordinati in base alla categoria

Figura 10: i prodotti vengono ordinati in base alla categoria (fare clic per visualizzare l'immagine full-size)

L'espressione di ordinamento viene ricordata quando si esegue il paging tramite i dati

Figura 11: L'espressione di ordinamento viene ricordata quando si esegue il paging dei dati (fare clic per visualizzare l'immagine a dimensioni complete)

Passaggio 6: Paging personalizzato tramite record in un ripetitore

L'esempio dataList esaminato nel passaggio 5 tramite i relativi dati usando la tecnica di paging predefinita inefficiente. Quando si esegue il paging di grandi quantità di dati, è imperativo usare il paging personalizzato. Nel paging efficiente tramite grandi quantità di dati e ordinamento di dati personalizzati sono state esaminate le differenze tra il paging predefinito e il paging personalizzato e i metodi creati nel BLL per l'uso di pagine personalizzate e l'ordinamento dei dati paginati personalizzati. In particolare, in queste due esercitazioni precedenti sono stati aggiunti i tre metodi seguenti alla ProductsBLL classe:

  • GetProductsPaged(startRowIndex, maximumRows) restituisce un determinato subset di record a partire da startRowIndex e non supera massimoRows.
  • GetProductsPagedAndSorted(sortExpression, startRowIndex, maximumRows) restituisce un determinato subset di record ordinati dal parametro di input sortExpression specificato.
  • TotalNumberOfProducts() fornisce il numero totale di record nella tabella di Products database.

Questi metodi possono essere usati per paginare in modo efficiente e ordinare i dati usando un controllo DataList o Repeater. Per illustrare questo problema, iniziare creando un controllo Repeater con supporto di paging personalizzato; verranno quindi aggiunte funzionalità di ordinamento.

Aprire la SortingWithCustomPaging.aspx pagina nella PagingSortingDataListRepeater cartella e aggiungere un ripetitore alla pagina, impostandone la ID proprietà su Products. Dallo smart tag di Repeater creare un nuovo oggetto ObjectDataSource denominato ProductsDataSource. Configurarlo per selezionare i dati dal ProductsBLL metodo della GetProductsPaged classe.

Configurare ObjectDataSource per usare il metodo GetProductsPaged della classe ProductsBLL

Figura 12: Configurare ObjectDataSource per usare il metodo class s GetProductsPaged (fare clic per visualizzare l'immagineProductsBLL full-size)

Impostare gli elenchi a discesa nelle schede UPDATE, INSERT e DELETE su (Nessuno) e quindi fare clic sul pulsante Avanti. La procedura guidata Configura origine dati richiede ora le origini dei GetProductsPaged parametri di input startRowIndex e maximumRows del metodo. In realtà, questi parametri di input vengono ignorati. Al contrario, i valori startRowIndex e maximumRows verranno passati tramite la Arguments proprietà nel gestore eventi objectDataSource, Selecting proprio come è stato specificato l'ordinamentoExpression in questa demo di esercitazione. Di conseguenza, lasciare gli elenchi a discesa dell'origine dei parametri nell'insieme di procedure guidate in None .

Lasciare le origini dei parametri impostate su Nessuna

Figura 13: Lasciare le origini dei parametri impostate su Nessuna (fare clic per visualizzare l'immagine a dimensioni complete)

Nota

Non impostare la proprietà trueObjectDataSource su EnablePaging . In questo modo, ObjectDataSource include automaticamente i propri parametri startRowIndex e maximumRows nell'elenco SelectMethod dei parametri esistenti. La EnablePaging proprietà è utile quando si associano dati paginati personalizzati a un controllo GridView, DetailsView o FormView perché questi controlli prevedono un comportamento determinato dall'oggetto ObjectDataSource disponibile solo quando EnablePaging la proprietà è true. Poiché è necessario aggiungere manualmente il supporto per il paging per DataList e Repeater, lasciare questa proprietà impostata su false (impostazione predefinita), perché si creerà nella funzionalità necessaria direttamente all'interno della pagina ASP.NET.

Infine, definire il ripetitore in ItemTemplate modo che venga visualizzato il nome, la categoria e il fornitore del prodotto. Dopo queste modifiche, la sintassi dichiarativa di Repeater e ObjectDataSource deve essere simile alla seguente:

<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>

Prendere un momento per visitare la pagina tramite un browser e notare che non vengono restituiti record. Ciò è dovuto al fatto che è ancora stato specificato i valori dei parametri startRowIndex e maximumRows ; pertanto, i valori di 0 vengono passati per entrambi. Per specificare questi valori, creare un gestore eventi per l'evento ObjectDataSource Selecting e impostare questi valori di parametri a livello di codice su valori hardcoded rispettivamente di 0 e 5:

protected void ProductsDataSource_Selecting
    (object sender, ObjectDataSourceSelectingEventArgs e)
{
    e.InputParameters["startRowIndex"] = 0;
    e.InputParameters["maximumRows"] = 5;
}

Con questa modifica, la pagina, quando visualizzata tramite un browser, mostra i primi cinque prodotti.

Vengono visualizzati i primi cinque record

Figura 14: vengono visualizzati i primi cinque record (fare clic per visualizzare l'immagine full-size)

Nota

I prodotti elencati nella figura 14 vengono ordinati in base al nome del prodotto perché la GetProductsPaged stored procedure che esegue la query di paging personalizzata efficiente ordina i risultati in ProductNamebase a .

Per consentire all'utente di passare le pagine, è necessario tenere traccia dell'indice di riga iniziale e delle righe massime e ricordare questi valori tra postback. Nell'esempio di paging predefinito sono stati usati campi querystring per rendere persistenti questi valori; per questa demo, consente di rendere persistenti queste informazioni nello stato di visualizzazione della pagina. Creare le due proprietà seguenti:

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;
    }
}

Aggiornare quindi il codice nel gestore eventi Selezione in modo che usi le StartRowIndex proprietà e MaximumRows anziché i valori hardcoded di 0 e 5:

e.InputParameters["startRowIndex"] = StartRowIndex;
e.InputParameters["maximumRows"] = MaximumRows;

A questo punto la pagina mostra ancora solo i primi cinque record. Tuttavia, con queste proprietà sul posto, si è pronti per creare l'interfaccia di paging.

Aggiunta dell'interfaccia di paging

Consente di usare la stessa interfaccia First, Previous, Next, Last paging usata nell'esempio di paging predefinito, incluso il controllo Web Label che visualizza la pagina dei dati in fase di visualizzazione e il numero di pagine totali. Aggiungere i quattro controlli Web Button e Etichetta sotto il ripetitore.

<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>

Click Creare quindi gestori eventi per i quattro pulsanti. Quando si fa clic su uno di questi pulsanti, è necessario aggiornare i StartRowIndex dati e ribinare i dati nel ripetitore. Il codice per i pulsanti First, Previous e Next è abbastanza semplice, ma per il pulsante Ultimo come si determina l'indice della riga iniziale per l'ultima pagina di dati? Per calcolare questo indice e essere in grado di determinare se è necessario abilitare i pulsanti Avanti e Ultimo, è necessario conoscere il numero di record totali visualizzati. È possibile determinare questa operazione chiamando il ProductsBLL metodo della TotalNumberOfProducts() classe. Consente di creare una proprietà a livello di pagina di sola lettura denominata TotalRowCount che restituisce i risultati del TotalNumberOfProducts() metodo:

private int TotalRowCount
{
    get
    {
        // Return the value from the TotalNumberOfProducts() method
        ProductsBLL productsAPI = new ProductsBLL();
        return productsAPI.TotalNumberOfProducts();
    }
}

Con questa proprietà è ora possibile determinare l'indice della riga iniziale dell'ultima pagina. In particolare, è il risultato intero del TotalRowCount meno 1 diviso per , moltiplicato per MaximumRowsMaximumRows. È ora possibile scrivere i Click gestori eventi per i quattro pulsanti dell'interfaccia di paging:

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();
}

Infine, è necessario disabilitare i pulsanti First e Previous nell'interfaccia di paging quando si visualizza la prima pagina di dati e i pulsanti Avanti e Ultimo quando si visualizza l'ultima pagina. A questo scopo, aggiungere il codice seguente al gestore eventi objectDataSource s 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;

Dopo aver aggiunto questi Click gestori eventi e il codice per abilitare o disabilitare gli elementi dell'interfaccia di paging in base all'indice di riga iniziale corrente, testare la pagina in un browser. Come illustrato nella figura 15, quando si visita la pagina i pulsanti First e Previous verranno disabilitati. Facendo clic su Avanti viene visualizzata la seconda pagina dei dati, mentre si fa clic su Last (vedere Le figure 16 e 17). Quando si visualizza l'ultima pagina di dati, entrambi i pulsanti Avanti e Ultimo sono disabilitati.

I pulsanti precedenti e ultimi sono disabilitati quando si visualizza la prima pagina dei prodotti

Figura 15: i pulsanti precedenti e ultimi sono disabilitati quando si visualizza la prima pagina dei prodotti (fare clic per visualizzare l'immagine full-size)

Viene visualizzata la seconda pagina dei prodotti

Figura 16: viene visualizzata la seconda pagina dei prodotti (fare clic per visualizzare l'immagine full-size)

Fare clic su Last Visualizza la pagina finale dei dati

Figura 17: fare clic sull'ultima visualizzazione della pagina finale dei dati (fare clic per visualizzare l'immagine a dimensioni complete)

Passaggio 7: Incluso il supporto di ordinamento con il ripetitore a pagina personalizzato

Ora che è stato implementato il paging personalizzato, è possibile includere il supporto per l'ordinamento. Il ProductsBLL metodo della GetProductsPagedAndSorted classe ha gli stessi parametri di input startRowIndex e maximumRows di GetProductsPaged, ma consente un parametro di input di sortExpression aggiuntivo. Per usare il GetProductsPagedAndSorted metodo da SortingWithCustomPaging.aspx, è necessario eseguire la procedura seguente:

  1. Modificare la proprietà ObjectDataSource s SelectMethod da GetProductsPaged a GetProductsPagedAndSorted.
  2. Aggiungere un oggetto sortExpressionParameter all'insieme ObjectDataSource.SelectParameters
  3. Creare una proprietà privata e a livello SortExpression di pagina che mantiene il valore tra postback tramite lo stato di visualizzazione della pagina.
  4. Aggiornare il gestore eventi objectDataSource s per assegnare il parametro ordinamento ObjectDataSource s SelectingsortExpression il valore della proprietà a livello SortExpression di pagina.
  5. Creare l'interfaccia di ordinamento.

Iniziare aggiornando la proprietà ObjectDataSource e SelectMethod aggiungendo un ordinamentoExpressionParameter. Assicurarsi che la proprietà sortExpressionParameter sia Type impostata su String. Dopo aver completato queste prime due attività, il markup dichiarativo di ObjectDataSource deve essere simile al seguente:

<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>

È quindi necessaria una proprietà a livello SortExpression di pagina il cui valore viene serializzato per visualizzare lo stato. Se non è stato impostato alcun valore dell'espressione di ordinamento, usare ProductName come impostazione predefinita:

private string SortExpression
{
    get
    {
        object o = ViewState["SortExpression"];
        if (o == null)
            return "ProductName";
        else
            return o.ToString();
    }
    set
    {
        ViewState["SortExpression"] = value;
    }
}

Prima di richiamare il GetProductsPagedAndSorted metodo ObjectDataSource, è necessario impostare sortExpressionParameter sul valore della SortExpression proprietà. Selecting Nel gestore eventi aggiungere la riga di codice seguente:

e.InputParameters["sortExpression"] = SortExpression;

Tutto ciò che rimane consiste nell'implementare l'interfaccia di ordinamento. Come illustrato nell'ultimo esempio, è possibile implementare l'interfaccia di ordinamento usando tre controlli Web Button che consentono all'utente di ordinare i risultati in base al nome del prodotto, alla categoria o al fornitore.

<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" />

Creare Click gestori eventi per questi tre controlli Button. Nel gestore eventi reimpostare l'oggetto StartRowIndex su 0, impostare sul SortExpression valore appropriato e ribinare i dati sul ripetitore:

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();
}

È tutto lì! Sebbene siano stati eseguiti diversi passaggi per ottenere paging e ordinamento personalizzati implementati, i passaggi erano molto simili a quelli necessari per il paging predefinito. La figura 18 mostra i prodotti durante la visualizzazione dell'ultima pagina dei dati quando vengono ordinati in base alla categoria.

Viene visualizzata l'ultima pagina dei dati ordinati per categoria

Figura 18: Viene visualizzata l'ultima pagina dei dati ordinati per categoria (fare clic per visualizzare l'immagine full-size)

Nota

Negli esempi precedenti, durante l'ordinamento da parte del fornitore SupplierName è stata usata come espressione di ordinamento. Tuttavia, per l'implementazione personalizzata del paging, è necessario usare CompanyName. Ciò avviene perché la stored procedure responsabile dell'implementazione del paging GetProductsPagedAndSorted personalizzato passa l'espressione di ordinamento nella ROW_NUMBER() parola chiave, la ROW_NUMBER() parola chiave richiede il nome effettivo della colonna anziché un alias. Pertanto, è necessario usare CompanyName (il nome della colonna nella Suppliers tabella) anziché l'alias usato nella SELECT query (SupplierName) per l'espressione di ordinamento.

Riepilogo

Né DataList né Repeater offrono supporto predefinito per l'ordinamento, ma con un bit di codice e un'interfaccia di ordinamento personalizzata, è possibile aggiungere tali funzionalità. Quando si implementa l'ordinamento, ma non si esegue il paging, è possibile specificare l'espressione di ordinamento tramite l'oggetto DataSourceSelectArguments passato al metodo ObjectDataSource.Select Questa DataSourceSelectArguments proprietà dell'oggetto SortExpression può essere assegnata nel gestore eventi objectDataSource s Selecting .

Per aggiungere funzionalità di ordinamento a un oggetto DataList o Repeater che fornisce già il supporto per il paging, l'approccio più semplice consiste nel personalizzare il livello della logica di business per includere un metodo che accetta un'espressione di ordinamento. Queste informazioni possono quindi essere passate tramite un parametro in ObjectDataSource s SelectParameters.

Questa esercitazione completa l'esame del paging e dell'ordinamento con i controlli DataList e Repeater. L'esercitazione successiva e finale esaminerà come aggiungere controlli Web Button ai modelli di DataList e Repeater per fornire alcune funzionalità personalizzate avviate dall'utente in base a ogni elemento.

Programmazione felice!

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Microsoft Web dal 1998. Scott lavora come consulente indipendente, allenatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2,0 in 24 Ore. Può essere raggiunto a mitchell@4GuysFromRolla.com. o tramite il suo blog, che può essere trovato in http://ScottOnWriting.NET.

Grazie speciali

Questa serie di esercitazioni è stata esaminata da molti revisori utili. Il revisore principale per questa esercitazione è stato David Suru. Interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com.