Passa ai contenuti principali

VB.NET : GridView con paginazione selezionata dall'utente

Sul sito della community romana del mondo .NET (www.dotnetromacesta.org) trovate un mio piccolo articolo su come realizzare un controllo ASP.NET, derivato dal controllo GridView, che permette all’utente di selezionare il numero di record da visualizzare.

Per semplicità riporto l’intero articolo rimandandovi al link di cui sopra per scaricare il file con il codice.

La nostra GridView modificherà il pager della GridView originale suddividendolo in due colonne, la prima delle quali conterrà il controllo di paginazione originale (normalmente contenuto in una cella con l’attributo ColumnSpan pari al numero di colonne della griglia), mentre la seconda conterrà una label e una drop down list con i possibili valori della paginazione (recuperati da una nuova proprietà che l’utente può impostare da codice).

Creiamo, dunque una classe che chiameremo DynamicPageSizeGridView e che deriverà dalla GridView contenuta nel namespace System.Web.UI.WebControls.

Definiamo tre proprietà pubbliche:

PageSizeList : elenco dei possibili valori selezionabili dall’utente. Si tratta di una stringa composta da valori numerici separati dal carattere “;” ;

PageSelectorText : testo che comparirà al fianco del controllo di selezione del numero di record;

PageSelectorCssClass : classe di stile della cella contenente la label e la dropdown di selezione.

Tutte e tre le proprietà sfruttano il viewstate per memorizzare i valori in modo da mantenerli tra un post back ed il successivo:

Public Property PageSelectorText() As String
   Get
        Dim _PageSelectorText = Me.ViewState("PageSelectorText")
        Return CStr(_PageSelectorText)
    End Get
    Set(ByVal value As String)
        Me.ViewState("PageSelectorText") = value
    End Set
End Property

Per creare fisicamente i controlli di gestione della paginazione, andiamo a gestire l’evento RowCreated ed in particolare ci occupiamo di agire sulla riga di tipo Pager:

Private Sub DynamicPageSizeGridView_RowCreated( _

        ByVal sender As Object, _
        ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) _
        Handles Me.RowCreated
    If e.Row.RowType = DataControlRowType.Pager Then
        Dim pagerControl = e.Row.Cells(0).Controls(0)
        e.Row.Cells(0).Controls.Clear()
        e.Row.Cells(0).Controls.Add(CreatePagerTable(pagerControl))
    End If
End Sub

In particolare andiamo a salvarci il controllo PagerTable che contiene il controllo di paginazione originale (che si trova nell’unica cella della riga di paginazione) e creiamo una tabella con una riga e due colonne. Nella prima di queste colonne (entrambe che occupano il 50% dello spazio) rimettiamo il paginatore originale, mentre nella seconda costruiamo i due controlli per la selezione del numero di record per pagina.

Function CreatePagerTable(ByVal pagerControl As Control) As Table
    Dim table = New Table()
    Dim row As New TableRow
    Dim pagerCell As New TableCell
    With pagerCell
        .Width = Unit.Percentage(50)
        .Controls.Add(pagerControl)
    End With
    row.Cells.Add(pagerCell)
    Dim sizeCell As New TableCell
    With sizeCell
        .CssClass = Me.PageSelectorCssClass
        .Width = Unit.Percentage(50)
        Dim label = New Label()
        label.Text = Me.PageSelectorText
        .Controls.Add(label)
        .Controls.Add(CreatePageSizeListDropDown())
    End With
    row.Cells.Add(sizeCell)
    table.Rows.Add(row)
    table.Width = Unit.Percentage(100)
    Return table
End Function

Nella funzione CreatePageSizeListDropDown creiamo la dropdown per la selezione della dimensione di paginazione:

Private Function CreatePageSizeListDropDown() As DropDownList
    Dim combo = New DropDownList()
    combo.Items.AddRange((From s In Me.PageSizeList.Split(CChar(";")) _
                      Where IsNumeric(s) _
                      Order By s Ascending _
                      Distinct Select New ListItem(s, s)).ToArray())
    combo.AutoPostBack = True
    combo.SelectedValue = Me.PageSize.ToString()
    AddHandler combo.SelectedIndexChanged, _
    AddressOf Me.ComboPageSizeSelectionChanged
    Return combo
End Function

Da notare l’utilizzo di LINQ per creare la lista dei valori possibili di paginazione contenuti nella proprietà PageSizeList.

Nell’evento di cambio dell’indice della dropdown effettuiamo il cambio di paginazione:

Protected Sub ComboPageSizeSelectionChanged( _
        ByVal sender As Object, _
        ByVal e As EventArgs)
    Dim combo = CType(sender, DropDownList)
    Dim selectedValue = combo.SelectedItem.Value
    Me.PageSize = System.Convert.ToInt32(selectedValue)
    Me.PageIndex = 0
End Sub

Recuperiamo il valore selezionato dall’utente, impostiamo il valore del PageSize e riportiamo il PageIndex a zero. Quest’ultima istruzione serve a garantire che, se ci si trova in una pagina diversa dalla prima e si seleziona una paginazione per cui esiste una sola pagina, non si abbia un errore.

A questo punto tutto sembra funzionare ma se selezioniamo una paginazione con un numero di record maggiore del numero di record totali della sorgente dati, scompare la riga di paginazione non consentendo più di cambiare il valore selezionato.

Per risolvere questo problema ci viene in aiuto un post di Ryan McDonnell(link) in cui si spiega come fare in modo di visualizzare sempre la riga di paginazione anche se il numero di record totali è minore del numero di record della pagina.

In sostanza è sufficiente implementare l’override della proprietà PageCount (utilizzata dal frame work per sapere quante pagine servono per visualizzare tutti i dati):

Public Overrides ReadOnly Property PageCount() As Integer
    Get
        Dim basePageCount = MyBase.PageCount
        If basePageCount = 1 Then
            Dim sf = New System.Diagnostics.StackFrame(1)
            If sf.GetMethod().Name = "CreateChildControls" _
                And sf.GetMethod().ReflectedType.Name = "GridView" Then
                    basePageCount += 1
            End If
        End If
        Return basePageCount
    End Get
End Property

Nel momento in cui ci si accorge che il numero di pagine necessarie per visualizzare i dati è pari ad 1 (cioè non viene visualizzata la riga di paginazione), si incrementa tale valore in modo da “ingannare” il framework e fargli , comunque, disegnare la riga di paginazione (priva del paginatore perché, effettivamente, non ci sono record su cui navigare).

In questo modo la nostra griglia è perfettamente funzionante.

Da notare che il tutto funziona sia con la paginazione lato server che con quella lato client.

Il codice sorgente è disponibile al seguente indirizzo

http://www.dotnetromacesta.org/common/articoli/aspnet/gridview/AspNet_GridView_Paginazione.aspx

Commenti

Post popolari in questo blog

VB.NET: Convertire un file DOC in RTF e PDF con office interop

In questo post vorrei proporvi del codice per poter convertire un file .doc in un file .rtf oppure .pdf utilizzando le API di interoperabilità di Office.Creeremo una classe, DocConverter, che esporrà le due funzionalità sopra citate.Cominciamo con il prevedere un attributo privato della classe che rappresenterà l’applicazione Word che utilizzeremo per la conversione. Creeremo l’istanza dell’attributo privato all’interno del costruttore della classe:PublicSubNew()
IfNot CreateWordApp() Then
ThrowNew ApplicationException("Assembly di interoperabilità con Office non trovato!")
EndIf
EndSub
Private _wordApp As Word.ApplicationClass
ProtectedFunction CreateWordApp() AsBoolean
Dim retval = True
Try
_wordApp = New Word.ApplicationClass()
_wordApp.Visible = False
Catch ex As System.Exception
_wordApp = Nothing
retval = False
EndTry
Return retval
EndFunction

La conversione del file doc sarà effettuata aprendo il file stesso ed eseguendo un’operazione di SaveAs:

Pr…

Cambiare la lingua di Visual Studio 2008

Oggi ho avuto qualche problema installando Windows Mobile 6 Professional SDK Refresh e Windows Mobile 6 Standard SDK Refresh.Scaricati i file di installazione e installati, ho provato a creare un progetto di tipo Windows Mobile 6.0 e mi sono beccato questo errore:Dopo qualche smanettamento abbiamo scoperto (e ringrazio il mitico Matteo per l’aiuto) che il mio Visual Studio 2008, pur essendo in Inglese (prova ne era il fatto che gli hotfix e la SP installata erano nella lingua di Albione) aveva come lingua impostata quella del sistema operativo (italiano).Ovviamente, non avrebbe mai potuto trovare la cartella 1040 (italiano) visto che l’installazione dell’SDK aveva supposto che la lingua del Visual Studio fosse Inglese (1033).La soluzione del problema è duplice:1) Duplicate la cartella 1033 presente nel percorso evidenziato dall’errore e la rinominate 10402) cambiate la lingua di Visual Studio.Per questa ultima eventualità basta andare nel menù Strumenti/Opzioni:e cambiare il linguaggi…

Tascam DR-05 registratore digitale per tutti

Diverso tempo fa ho acquistato il registratore digitale Tascam DR-05 e, ora, dopo diversi mesi di utilizzo, posso dire la mia a proposito.

Si tratta di un ottimo registratore digitale con microfono stereo che permette di ottenere registrazioni di ottima qualitaà anche in ambienti non perfetti dal punto di vista acustico.

Interessante la possibilità di utilizzare un cavalletto di piccole dimensioni come HAMA Mini treppiede o Mini Cavalletto Universale per tenere il microfono sollevato dal tavolo in fase di registrazione grazie allàattacco universale per macchina fotografica che il microfono ha nella parte inferiore.

Da segnalare anche il menu’ ben fatto e la possibilita’ di utilizzare una scheda SD esterna per memorizzare i file audio. Anche a livello di consumo batterie non e’ niente male. Consiglio l’uso delle alcaline non ricaricabili.

Il mio utilizzo e’ stato prettamente di registrazione di podcast vocali (no musica) ma le recensioni confermano che se la cava egregiamente con la mu…