Quando si vogliono paginare i dati da visualizzare in un
datalist (con il datagrid il problema non sussiste dato che è gia predisposto) si può utilizzare il metodo
Fill del
(Oledb/SQL)DataAdapter specificando il range, ma se non si dispone (come un file xml) di una sorgente di dati che permette l'uso di un dataadapter non si puo optare per questa soluzione.
Il framework ci viene incontro ugualmente infatti,ci si può affidare al metodo
ReadXml offerto dalla classe dataset per accedere direttamente ad un file xml (ovvero a qualsiasi fonte xml valida come webservice etc....) dove sono salvati i dati.
Il problema è che l'struzione legge tutti i dati e non si puo paginare in fase di lettura ma si deve ricorrere a qualche trucchetto.
Prepariamo una pagina con un dropdownlist dove scelgo quanti per record pagina, un datalist e degli hyperlink che mi servono per la navigazione tra le pagine. Quindi per prima cosa leggiamo il file :
Dim ds As New System.Data.DataSet
ds.ReadXml(Server.MapPath("miofile.xml"))
a questo punto il dataset contiene tutti i record e dobbiamo decidere quali visualizzare.Ci dobbiamo affidare al qualche parametro che leggeremo dalla querystring (
num=numero di righe per pagina ,
pag=numero di pagina da visualizzare) che mi indichi cosa mostrare, parametri che man mano che clicchiamo sui link "Avanti" e "Indietro" serviranno. Inoltre leggiamo il numero di righe che serve per visualizzare o meno il pulsante avanti (caso in cui visualizzo l'ultima pagina)
Dim zNumero As Int16 = Request.QueryString("num")
Dim zPag As Int16 = Request.QueryString("pag")
Dim zRecords As Int16 = ds.Tables(0).Rows.Count
If zNumero <> 0 Then
linkAvanti.NavigateUrl = Request.Url.LocalPath & "?num=" & zNumero & "&pag=" & zPag + 1
linkAvanti.Visible = (zRecords - 1) >= (zPag + 1) * zNumero
LinkIndietro.NavigateUrl = Request.Url.LocalPath & "?num=" & zNumero & "&pag=" & zPag - 1
LinkIndietro.Visible = zPag <> 0
Else
linkAvanti.Visible = False
LinkIndietro.Visible = False
End If
A questo punto loopiamo aggiungendo ad un arraylist le righe che ci soddisfano (controllando con [If i <= zRecords - 1] che non siano finite)
Dim arr As New ArrayList
For i As Integer = zPag * zNumero To zPag * zNumero + zNumero - 1
If i <= zRecords - 1 Then arr.Add(ds.Tables(0).Rows(i))
Next
infine agganciamo il datasource al mio datalist
DataList1.DataSource = arr
DataList1.DataBind()
Il progetto in esecuzione
Tutta questa parte di codice puo essere inserita nella funzione page_load controllando il postback mentre per quanto riguarda la parte Html della pagina all'interno del tag
<ItemTemplate> del datalist devo usare il tag speciale
<%# DataBinder.Eval(Container, "DataItem(2)") %> che come si nota subito non va per nome del campo da visualizzare ma per indice, cosa che si rende necessaria perche il datasource è un arraylist e non un datatable/dataset/dataview ai quali si può accedere tramite nome.
Pro:- La comodità che con un semplice copia incolla si distribuisce la pagina e il relativo file da leggere indipendentemente dalla locazione senza preoccuparsi connessioni a database (e magari tramite un'altra pagina scrivere con il duale
WriteXml )
- Si ottiene lo stesso risultato pur non disponendo di un metodo gajardo come fill del dataadapter
Contro: - Il file viene letto interamente anche per visualizzare solo determinati record percui si deve stare attenti alle dimensioni del file stesso
- Si utilizza un oggetto arraylist "contenitore" delle righe e datasource del datalist, percui nella parte html della pagina si deve andare per indice e non per nome del campo