Ordinamento dei dati in un controllo DataList o Repeater (VB)
In questa esercitazione verrà illustrato come includere il supporto per l'ordinamento in DataList e Repeater, nonché come costruire un oggetto DataList o Repeater i cui dati possono essere distribuiti e ordinati.
Introduzione
Nell'esercitazione precedente è stato illustrato 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 visualizza solo la pagina di dati richiesta. Questa tecnica è simile a quella usata internamente dai controlli GridView, DetailsView e FormView per offrire la funzionalità predefinita di paging predefinita.
Oltre a offrire supporto per il paging, GridView include anche il supporto per l'ordinamento predefinito. Né DataList né Repeater forniscono funzionalità di ordinamento predefinite; Tuttavia, le funzionalità di ordinamento possono essere aggiunte 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 oggetto DataList o Repeater i cui dati possono essere distribuiti e ordinati.
Revisione dell'ordinamento
Come illustrato nell'esercitazione Sul paging e l'ordinamento dei dati del report , il controllo GridView offre supporto per l'ordinamento predefinito. 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 valore di proprietà ha il SortExpression
rendering dell'intestazione come LinkButton. Quando un utente fa clic su un'intestazione specifica del campo GridView, si verifica un postback e i dati vengono ordinati in base al campo selezionato s SortExpression
.
Anche il controllo GridView dispone di una SortExpression
proprietà che archivia l'oggetto SortExpression
del campo GridView in base al quale 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'ordinamento viene attivato o disattivato).
Quando GridView è associato al controllo origine dati, passa le relative SortExpression
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
- Ricordare il campo dati per l'ordinamento e se ordinare in ordine crescente o decrescente
- Indicare a ObjectDataSource di ordinare i dati in base a un campo dati specifico
Queste tre attività verranno affrontate nei passaggi 3 e 4. In seguito, si esaminerà come includere sia il supporto di paging che di ordinamento in un oggetto DataList o Repeater.
Passaggio 2: Visualizzazione dei prodotti in un ripetitore
Prima di preoccuparsi dell'implementazione di una delle funzionalità correlate all'ordinamento, è possibile iniziare elencando i prodotti in un controllo Repeater. Per iniziare, aprire 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 ObjectDataSource denominato ProductsDataSource
e configurarlo per recuperare i dati dal ProductsBLL
metodo della GetProducts()
classe. Selezionare l'opzione (Nessuno) negli elenchi a discesa nelle schede INSERT, UPDATE e DELETE.
Figura 1: Creare un oggetto ObjectDataSource e configurarlo per l'uso del metodo (fare clic per visualizzare l'immagineGetProductsAsPagedDataSource()
a dimensione intera)
Figura 2: Impostare il Drop-Down Elenchi nelle schede UPDATE, INSERT e DELETE su (Nessuno) (Fare clic per visualizzare l'immagine a dimensione intera)
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 questo ItemTemplate
elemento in modo dichiarativo, poiché lo smart tag del controllo Repeater non dispone dell'opzione Modifica modelli trovata in DataList s. Si userà lo stesso ItemTemplate
dell'esercitazione precedente, che visualizzava il nome, il fornitore e la categoria del prodotto.
Dopo aver aggiunto ItemTemplate
, il markup dichiarativo repeater e ObjectDataSource dovrebbe 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 viene visualizzata tramite un browser.
Figura 3: Viene visualizzato il nome, il fornitore e la categoria di ogni prodotto (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 3: Indicare a ObjectDataSource di ordinare i dati
Per ordinare i dati visualizzati in Repeater, è necessario informare ObjectDataSource dell'espressione di ordinamento in base alla quale devono essere ordinati i dati. Prima che ObjectDataSource recuperi i dati, viene generato il relativo Selecting
evento, che offre l'opportunità di specificare un'espressione di ordinamento. Al 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 Sub ProductsDataSource_Selecting(ByVal sender As Object, _
ByVal e As ObjectDataSourceSelectingEventArgs) _
Handles ProductsDataSource.Selecting
e.Arguments.SortExpression = sortExpression
End Sub
Al valore sortExpression deve essere assegnato il nome del campo dati per ordinare i dati, ad esempio ProductName . Non esiste alcuna proprietà correlata 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 .
Procedere 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.
Figura 4: I prodotti vengono ordinati in base al nome in ordine alfabetico inverso (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 4: Creazione dell'interfaccia di ordinamento e memorizzazione dell'espressione e della direzione di ordinamento
L'attivazione del supporto per l'ordinamento in GridView converte ogni testo di intestazione del campo ordinabile in un controllo LinkButton che, quando si fa clic, ordina i dati di conseguenza. Un'interfaccia di ordinamento di questo tipo ha senso per GridView, in cui i dati sono disposti in modo ordinato 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 un'interfaccia di questo tipo per questa esercitazione.
Aggiungere un controllo Web DropDownList sopra il SortableProducts
Repeater e impostarne la ID
proprietà su SortBy
. Nella Finestra Proprietà fare clic sui puntini di sospensione nella Items
proprietà per visualizzare l'insieme ListItem Editor. Aggiungere ListItem
s per ordinare i dati in base ai ProductName
campi , CategoryName
e SupplierName
. Aggiungere anche un ListItem
oggetto per ordinare i prodotti in base al nome in ordine alfabetico inverso.
Le ListItem
Text
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 .
Figura 5: Aggiungere un ListItem
oggetto per ognuno dei campi dati ordinabili
Infine, aggiungere un controllo Web Button a destra di DropDownList. Impostare su ID
RefreshRepeater
e la relativa Text
proprietà su Refresh .
Dopo la creazione di s e l'aggiunta ListItem
del pulsante Aggiorna, la sintassi dichiarativa dropDownList e Button dovrebbe 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" />
Al termine dell'ordinamento DropDownList, è necessario aggiornare il gestore eventi di ObjectDataSource in Selecting
modo che usi la proprietà selezionata SortBy``ListItem
Value
anziché un'espressione di ordinamento hardcoded.
Protected Sub ProductsDataSource_Selecting _
(ByVal sender As Object, ByVal e As ObjectDataSourceSelectingEventArgs) _
Handles ProductsDataSource.Selecting
' Have the ObjectDataSource sort the results by the
' selected sort expression
e.Arguments.SortExpression = SortBy.SelectedValue
End Sub
A questo punto, quando si visita la pagina, i prodotti verranno inizialmente ordinati in base al ProductName
campo dati, perché è SortBy
ListItem
selezionato per impostazione predefinita (vedere la figura 6). Se si seleziona un'opzione di ordinamento diversa, ad esempio Categoria e si fa clic su Aggiorna, si verificherà un postback e si riordinano i dati in base al nome della categoria, come illustrato nella figura 7.
Figura 6: I prodotti vengono inizialmente ordinati in base al nome (fare clic per visualizzare l'immagine a dimensione intera)
Figura 7: I prodotti sono ora ordinati per categoria (fare clic per visualizzare l'immagine a dimensione intera)
Nota
Se si fa clic sul pulsante Aggiorna, i dati vengono riordinati automaticamente perché lo stato di visualizzazione del ripetitore è stato disabilitato, in modo che il ripetitore venga riassociato all'origine dati in ogni postback. Se lo stato di visualizzazione del ripetitore è stato abilitato, la modifica dell'elenco a discesa di ordinamento non avrà alcun effetto sull'ordinamento. Per risolvere questo problema, creare un gestore eventi per l'evento Refresh Button s Click
e riassociare il Repeater alla relativa origine dati (chiamando il metodo Repeater).DataBind()
Memorizzazione dell'espressione di ordinamento e della direzione
Quando si crea un oggetto DataList o Repeater ordinabile in una pagina in cui possono verificarsi postback non correlati all'ordinamento, è fondamentale ricordare l'espressione di ordinamento e la direzione tra i 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 ricollegare i dati al Ripetitore. Se i dettagli di ordinamento non vengono salvati in modo permanente nel postback, i dati visualizzati sullo schermo verranno ripristinati nell'ordinamento originale.
Per questa esercitazione, DropDownList salva in modo implicito l'espressione di ordinamento e la direzione nello stato di visualizzazione. Se si usasse un'interfaccia di ordinamento diversa con, ad esempio LinkButtons che fornisce le varie opzioni di ordinamento, è necessario tenere presente l'ordinamento tra i postback. Questa operazione può essere eseguita archiviando i parametri di ordinamento nello stato di visualizzazione della pagina, includendo il parametro di ordinamento nella stringa di query o tramite un'altra tecnica di persistenza dello stato.
Gli esempi futuri di questa esercitazione illustrano come rendere persistenti i dettagli di ordinamento nello stato di visualizzazione della pagina.
Passaggio 5: Aggiunta del supporto per l'ordinamento a un oggetto DataList 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 di paging. Per iniziare, aprire 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 di SortingWithDefaultPaging.aspx
tra i <asp:Content>
tag.
Figura 8: Replicare il markup dichiarativo nei <asp:Content>
tag da Paging.aspx
a SortingWithDefaultPaging.aspx
(fare clic per visualizzare l'immagine a dimensione intera)
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
. Successivamente, dedicare qualche minuto alla visualizzazione della SortingWithDefaultPaging.aspx
pagina in un browser. 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 se 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 objectDataSource.Selecting
Questa operazione funziona correttamente quando ObjectDataSource viene restituito un oggetto che può essere ordinato, come l'oggetto ProductsDataTable
restituito dal GetProducts()
metodo . Tuttavia, l'oggetto restituito dal GetProductsAsPagedDataSource
metodo non supporta l'ordinamento PagedDataSource
dell'origine 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 l'oggetto ProductsDataTable
restituito dal GetProducts()
metodo , specificare la Sort
proprietà del valore predefinito DataTableView
:
<System.ComponentModel.DataObjectMethodAttribute _
(System.ComponentModel.DataObjectMethodType.Select, False)> _
Public Function GetProductsSortedAsPagedDataSource _
(sortExpression As String, pageIndex As Integer, pageSize As Integer) _
As PagedDataSource
' Get ALL of the products
Dim products As Northwind.ProductsDataTable = GetProducts()
'Sort the products
products.DefaultView.Sort = sortExpression
' Limit the results through a PagedDataSource
Dim pagedData As New PagedDataSource()
pagedData.DataSource = products.DefaultView
pagedData.AllowPaging = True
pagedData.CurrentPageIndex = pageIndex
pagedData.PageSize = pageSize
Return pagedData
End Function
Il GetProductsSortedAsPagedDataSource
metodo è leggermente diverso dal GetProductsAsPagedDataSource
metodo creato nell'esercitazione precedente. In particolare, GetProductsSortedAsPagedDataSource
accetta un parametro sortExpression
di input aggiuntivo e assegna questo valore alla Sort
proprietà dell'oggetto ProductDataTable
.DefaultView
Alcune righe di codice in un secondo momento, all'oggetto PagedDataSource
dataSource viene assegnato .ProductDataTable
DefaultView
Chiamata al metodo GetProductsSortedAsPagedDataSource e specifica del valore per il parametro di input SortExpression
Al termine del GetProductsSortedAsPagedDataSource
metodo, il 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 attraverso i due QueryStringParameters
, specificati nell'insieme SelectParameters
. Questi due QueryStringParameters
indicano che l'origine per i parametri pageIndex e pageSize del GetProductsAsPagedDataSource
metodo provengono dai campi pageIndex
querystring e pageSize
.
Aggiornare la proprietà ObjectDataSource in SelectMethod
modo che richiami il nuovo GetProductsSortedAsPagedDataSource
metodo. Aggiungere quindi un nuovo QueryStringParameter
oggetto in modo che il parametro di input sortExpression sia accessibile dal campo sortExpression
querystring . Impostare s QueryStringParameter
DefaultValue
su ProductName .
Dopo queste modifiche, il markup dichiarativo di ObjectDataSource dovrebbe 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). Il motivo è che, per impostazione predefinita, un valore productName viene passato come parametro sortExpression del GetProductsSortedAsPagedDataSource
metodo.
Figura 9: Per impostazione predefinita, i risultati vengono ordinati per ProductName
(fare clic per visualizzare l'immagine a dimensione intera)
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 stringa di query quando si passa a una pagina di dati diversa. Infatti, facendo clic sui pulsanti Avanti o Ultima pagina ci riporta a Paging.aspx
! Inoltre, attualmente non esiste alcuna interfaccia di ordinamento. L'unico modo in cui un utente può modificare l'ordinamento dei dati di paging consiste nel modificare direttamente la stringa di query.
Creazione dell'interfaccia di ordinamento
Prima di tutto è necessario aggiornare il RedirectUser
metodo per inviare l'utente a SortingWithDefaultPaging.aspx
(anziché Paging.aspx
a ) e per includere il sortExpression
valore nella stringa di query. È anche necessario aggiungere una proprietà denominata SortExpression
a livello di pagina di sola lettura. Questa proprietà, analogamente alle PageIndex
proprietà e PageSize
create nell'esercitazione precedente, restituisce il valore del sortExpression
campo querystring, se esistente, e il valore predefinito ( ProductName ) in caso contrario.
Attualmente il RedirectUser
metodo accetta solo un singolo parametro di input da visualizzare nell'indice della pagina. In alcuni casi, tuttavia, potrebbe essere necessario 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 l'ordinamento dei 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 di pagina e l'espressione di ordinamento.
Private ReadOnly Property SortExpression() As String
Get
If Not String.IsNullOrEmpty(Request.QueryString("sortExpression")) Then
Return Request.QueryString("sortExpression")
Else
Return "ProductName"
End If
End Get
End Property
Private Sub RedirectUser(ByVal sendUserToPageIndex As Integer)
' Use the SortExpression property to get the sort expression
' from the querystring
RedirectUser(sendUserToPageIndex, SortExpression)
End Sub
Private Sub RedirectUser(ByVal sendUserToPageIndex As Integer,
ByVal sendUserSortingBy As String)
' 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))
End Sub
Nel primo esempio di questa esercitazione è stata creata un'interfaccia di ordinamento usando un oggetto DropDownList. Per questo esempio, è possibile usare tre controlli Web Button posizionati sopra DataList uno per l'ordinamento ProductName
in base a , uno per CategoryName
e 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 di essi. I gestori eventi devono chiamare il RedirectUser
metodo , restituendo l'utente alla prima pagina usando l'espressione di ordinamento appropriata.
Protected Sub SortByProductName_Click(sender As Object, e As EventArgs) _
Handles SortByProductName.Click
'Sort by ProductName
RedirectUser(0, "ProductName")
End Sub
Protected Sub SortByCategoryName_Click(sender As Object, e As EventArgs) _
Handles SortByCategoryName.Click
'Sort by CategoryName
RedirectUser(0, "CategoryName")
End Sub
Protected Sub SortBySupplierName_Click(sender As Object, e As EventArgs) _
Handles SortBySupplierName.Click
'Sort by SupplierName
RedirectUser(0, "SupplierName")
End Sub
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. Verrà visualizzata la prima pagina di dati, ordinata in base al nome della categoria (vedere la figura 10). Analogamente, facendo clic sul pulsante Ordina per fornitore i dati viene ordinato in base al fornitore a partire dalla prima pagina di dati. La scelta di ordinamento viene memorizzata come i dati vengono sottoposti a paging. La figura 11 mostra la pagina dopo l'ordinamento per categoria e quindi l'avanzamento alla tredicesima pagina di dati.
Figura 10: I prodotti sono ordinati per categoria (fare clic per visualizzare l'immagine a dimensione intera)
Figura 11: L'espressione di ordinamento viene memorizzata durante il paging dei dati (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 6: Paging personalizzato tra record in un ripetitore
L'esempio DataList esaminato nei passaggi 5 tramite i dati usando la tecnica di paging predefinita inefficiente. Quando si esegue il paging in quantità di dati sufficientemente grandi, è fondamentale usare il paging personalizzato. Nel paging efficiente tramite grandi quantità di dati e l'ordinamento di dati con paging personalizzati sono state esaminate le differenze tra il paging predefinito e personalizzato e i metodi creati nel BLL per l'utilizzo di pagine personalizzate e l'ordinamento di dati di paging personalizzati. In particolare, in queste due esercitazioni precedenti sono stati aggiunti i tre metodi seguenti alla ProductsBLL
classe :
GetProductsPaged(startRowIndex, maximumRows)
restituisce un subset specifico di record a partire da startRowIndex e non supera maximumRows.GetProductsPagedAndSorted(sortExpression, startRowIndex, maximumRows)
restituisce un subset specifico di record ordinati in base al parametro di input sortExpression specificato.TotalNumberOfProducts()
fornisce il numero totale di record nella tabella diProducts
database.
Questi metodi possono essere usati per eseguire in modo efficiente la pagina 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 Repeater creare un nuovo ObjectDataSource denominato ProductsDataSource
. Configurarlo per selezionarne i dati dal ProductsBLL
metodo della GetProductsPaged
classe .
Figura 12: Configurare ObjectDataSource per l'uso del metodo della GetProductsPaged
classe (fare clic per visualizzare l'immagineProductsBLL
a dimensione intera)
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 parametri di GetProductsPaged
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 di Selecting
ObjectDataSource, esattamente come è stato specificato l'ordinamentoExpression nella prima demo dell'esercitazione. Lasciare quindi gli elenchi a discesa origine parametri nella procedura guidata impostata su Nessuno.
Figura 13: Lasciare le origini dei parametri impostate su Nessuno (fare clic per visualizzare l'immagine a dimensione intera)
Nota
Non impostare la proprietà true
ObjectDataSource su EnablePaging
. In questo modo ObjectDataSource includerà automaticamente i propri parametri startRowIndex e maximumRows nell'elenco SelectMethod
di parametri esistenti. La EnablePaging
proprietà è utile quando si associano dati di paging personalizzati a un controllo GridView, DetailsView o FormView perché questi controlli prevedono un determinato comportamento da 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é verrà creata la funzionalità necessaria direttamente all'interno della pagina ASP.NET.
Infine, definire il repeater in ItemTemplate
modo che vengano visualizzati il nome, la categoria e il fornitore del prodotto. Dopo queste modifiche, la sintassi dichiarativa repeater e ObjectDataSource dovrebbe 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>
Dedicare qualche minuto a 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 0 vengono passati per entrambi. Per specificare questi valori, creare un gestore eventi per l'evento ObjectDataSource e Selecting
impostare questi valori di parametri a livello di codice sui valori hardcoded di 0 e 5, rispettivamente:
Protected Sub ProductsDataSource_Selecting(sender As Object, _
e As ObjectDataSourceSelectingEventArgs) _
Handles ProductsDataSource.Selecting
e.InputParameters("startRowIndex") = 0
e.InputParameters("maximumRows") = 5
End Sub
Con questa modifica, la pagina, visualizzata tramite un browser, mostra i primi cinque prodotti.
Figura 14: Vengono visualizzati i primi cinque record (fare clic per visualizzare l'immagine a dimensione intera)
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 base a ProductName
.
Per consentire all'utente di scorrere le pagine, è necessario tenere traccia dell'indice di riga iniziale e delle righe massime e ricordare questi valori tra i 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 Property StartRowIndex() As Integer
Get
Dim o As Object = ViewState("StartRowIndex")
If o Is Nothing Then
Return 0
Else
Return CType(o, Integer)
End If
End Get
Set(ByVal value As Integer)
ViewState("StartRowIndex") = value
End Set
End Property
Private Property MaximumRows() As Integer
Get
Dim o As Object = ViewState("MaximumRows")
If o Is Nothing Then
Return 5
Else
Return CType(o, Integer)
End If
End Get
Set(ByVal value As Integer)
ViewState("MaximumRows") = value
End Set
End Property
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") = 0
e.InputParameters("maximumRows") = 5
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 ReadOnly Property TotalRowCount() As Integer
Get
'Return the value from the TotalNumberOfProducts() method
Dim productsAPI As New ProductsBLL()
Return productsAPI.TotalNumberOfProducts()
End Get
End Property
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 MaximumRows
MaximumRows
. È ora possibile scrivere i Click
gestori eventi per i quattro pulsanti dell'interfaccia di paging:
Protected Sub FirstPage_Click(sender As Object, e As EventArgs) _
Handles FirstPage.Click
'Return to StartRowIndex of 0 and rebind data
StartRowIndex = 0
Products.DataBind()
End Sub
Protected Sub PrevPage_Click(sender As Object, e As EventArgs) _
Handles PrevPage.Click
'Subtract MaximumRows from StartRowIndex and rebind data
StartRowIndex -= MaximumRows
Products.DataBind()
End Sub
Protected Sub NextPage_Click(sender As Object, e As EventArgs) _
Handles NextPage.Click
'Add MaximumRows to StartRowIndex and rebind data
StartRowIndex += MaximumRows
Products.DataBind()
End Sub
Protected Sub LastPage_Click(sender As Object, e As EventArgs) _
Handles LastPage.Click
'Set StartRowIndex = to last page's starting row index and rebind data
StartRowIndex = ((TotalRowCount - 1) \ MaximumRows) * MaximumRows
Products.DataBind()
End Sub
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
Dim LastPageStartRowIndex As Integer = _
((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.
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)
Figura 16: viene visualizzata la seconda pagina dei prodotti (fare clic per visualizzare l'immagine full-size)
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:
- Modificare la proprietà ObjectDataSource s
SelectMethod
daGetProductsPaged
aGetProductsPagedAndSorted
. - Aggiungere un oggetto sortExpression
Parameter
all'insieme ObjectDataSource.SelectParameters
- Creare una proprietà privata e a livello
SortExpression
di pagina che mantiene il valore tra postback tramite lo stato di visualizzazione della pagina. - Aggiornare il gestore eventi objectDataSource s per assegnare il parametro ordinamento ObjectDataSource s
Selecting
sortExpression il valore della proprietà a livelloSortExpression
di pagina. - 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 Property SortExpression() As String
Get
Dim o As Object = ViewState("SortExpression")
If o Is Nothing Then
Return "ProductName"
Else
Return o.ToString()
End If
End Get
Set(ByVal value As String)
ViewState("SortExpression") = value
End Set
End Property
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 Sub SortByProductName_Click(sender As Object, e As EventArgs) _
Handles SortByProductName.Click
StartRowIndex = 0
SortExpression = "ProductName"
Products.DataBind()
End Sub
Protected Sub SortByCategoryName_Click(sender As Object, e As EventArgs) _
Handles SortByCategoryName.Click
StartRowIndex = 0
SortExpression = "CategoryName"
Products.DataBind()
End Sub
Protected Sub SortBySupplierName_Click(sender As Object, e As EventArgs) _
Handles SortBySupplierName.Click
StartRowIndex = 0
SortExpression = "CompanyName"
Products.DataBind()
End Sub
È 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.
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.
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per