

| com exemplos em VB |
| Componente para deixar forms em Vb semelhantes às telas do winnamp |
| Componente para colocar sua aplicação VB no Systray |
| Componente para transformar sua aplicação VB em serviço |
| Ferramentas úteis para quem usa Olap Server |
| |

![]() |
||||||||
|
|
||||||||
Lembro-me da primeira vez que montei uma datagrid com paginação no .NET uma das primeiras observações que fiz foi algo como "Será que não dá para personalizar ? Pelo menos usar os números e o botão anterior e próximo ao mesmo tempo ?"
A questão é que dá. Os WebControls são altamente personalizáveis e a datagrid não é uma excessão, muito pelo contrário.
Então vamos lá, personalizar o pager. Para fazer isso, partimos de uma grid já vinculada e com a paginação funcionando e deveremos programar o evento itemcreated. Esse evento ocorre a cada item da grid que é criado.
Dentro do evento itemCreated precisamos garantir que nosso código só será rodado no momento da criação do pager e não para cada célula da Grid. Um IF pode nos garantir isso, veja :
If e.Item.ItemType = ListItemType.Pager Then
End If
Vamos então definir uma variável pager para podermos manipular
o pager mais facilmente. O pager é, basicamente, uma tablecell, definiremos
a variável desta forma.
Dim pager as TableCell
If e.Item.ItemType = ListItemType.Pager Then
pager=e.item.controls(0)
End If
Observe como utilizamos Controls(0) do e.item. E.item representa uma linha
da grid, controls(0) a primeira célula da linha, que é o pager.
Precisamos vasculhar os controles contidos dentro do pager. Vamos partir do principio que configuramos a paginação da grid como sendo uma paginação numérica e vamos alterar a formatação dos números.
Cada número de página dentro do pager é um objeto do tipo System.Web.UI.WebControls.DataGridLinkButton , que é uma classe criada a partir da classe linkButton, portanto podemos tratar esses objetos como linkButton.
A página atual, porém, é representada por uma classe criada a partir da classe label, portanto também pode ser tratada como um label.
Porém entre um objeto e outro existe um espaço em branco ( ). Por estranho que pareça, um espaço em branco também é um objeto, objeto literal, pelo qual passaremos ao vasculharmos a coleção de objetos filhos do pager. Por isso ao fazermos um loop na coleção de controles devemos fazer o loop saltando de 2 em 2, para pular o objeto literal existente entre os demais.
Precisaremos então de um contador e de uma variável do tipo WebControl para manipularmos os controles. Veja como fica o código agora :
Dim pager as TableCell
Dim wc as WebControl
Dim cnt as Integer
If e.Item.ItemType = ListItemType.Pager Then
pager=e.item.controls(0)
For cnt = 0 To pager.Controls.Count - 1 Step 2
wc = pager.Controls(cnt)
Next
End If
O próximo passo é fazermos um IF para decidir o que fazer : Se for um linkbutton formataremos de uma forma, se for um label, formataremos de outra forma, veja :
Dim pager as TableCell
Dim wc as WebControl
Dim cnt as Integer
If e.Item.ItemType = ListItemType.Pager Then
pager=e.item.controls(0)
For cnt = 0 To pager.Controls.Count - 1 Step 2
wc = pager.Controls(cnt)
If wc.GetType.ToString() = "System.Web.UI.WebControls.DataGridLinkButton" Then
CType(wc, LinkButton).Text = "[" & CType(wc, LinkButton).Text & "]"
Else
CType(wc, Label).Text = "Página " & CType(wc, Label).Text
End If
Next
End If
Desta forma nossa aplicação já roda e temos um formato
de pager personalizado, com os números de página aparecendo
entre colchetes e com a página atual aparecendo em destaque com a palavra
"Página".
Conseguir uma formatação personalizada foi apenas o primeiro passo, vamos agora inserir controles adicionais. Partindo do exemplo que citei, vamos inserir dois linkbuttons, um "Próximo" ao final dos números de página e um "Anterior" ao inicio da numeração de página. Desta forma precisamos de outra variável, do tipo linkbutton.
Precisaremos primeiramente de 2 subs que tratem o evento click dos linkbuttons que criaremos. Essas subs precisam atender a assinatura do evento click da classe linkbutton, veja como ficam :
Sub proximo(ByVal sender As Object, ByVal e As System.EventArgs)
DG.CurrentPageIndex = DG.CurrentPageIndex + 1
carregagrid()
End Sub
Sub anterior(ByVal sender As Object, ByVal e As System.EventArgs)
DG.CurrentPageIndex = DG.CurrentPageIndex - 1
carregagrid()
End Sub
Agora veja como fica o evento itemCreated para criar os objetos linkButton
:
Dim pager as TableCell
Dim wc as WebControl
Dim cnt as Integer
Dim lnk As LinkButton
If e.Item.ItemType = ListItemType.Pager Then
pager=e.item.controls(0)
For cnt = 0 To pager.Controls.Count - 1 Step 2
wc = pager.Controls(cnt)
If wc.GetType.ToString() = "System.Web.UI.WebControls.DataGridLinkButton" Then
CType(wc, LinkButton).Text = "[" & CType(wc, LinkButton).Text & "]"
Else
CType(wc, Label).Text = "Página " & CType(wc, Label).Text
End If
Next
'Definição do botão próximo
lnk = New LinkButton()
lnk.Text = "Proximo"
AddHandler lnk.Click, AddressOf proximo
pager.Controls.Add(lnk)
'Definição do botão anterior
lnk = New LinkButton()
lnk.Text = "Anterior"
AddHandler lnk.Click, AddressOf anterior
pager.Controls.AddAt(0, lnk)
End If
Algumas questões são interessantes de serem observadas :
O uso do AddHandler é uma novidade no ambiente .NET para adicionar tratadores de evento via código, o que sem dúvida é um excelente recurso.
O AddAt é um método bem útil de um objeto collection, nos permitindo adicionar um item em uma posição específica
É interessante observar a facilidade com que podemos utilizar o Add na coleção controls de um objeto contido no webform.
Ao executar a aplicação com esse código você observará
que os botões próximo e anterior ficaram colados aos números
que estão ao seu lado. Isso porque falta justamente um espaço
em branco entre os objetos, o objeto literal que nos fez saltar de dois em
dois no laço. Vejamos como fica o código com a criação
do objeto Literal :
Dim pager as TableCell
Dim wc as WebControl
Dim cnt as Integer
Dim lnk As LinkButton
Dim lt As Literal
If e.Item.ItemType = ListItemType.Pager Then
pager = e.Item.Controls(0)
For cnt = 0 To pager.Controls.Count - 1 Step 2
wc = pager.Controls(cnt)
If wc.GetType.ToString() = "System.Web.UI.WebControls.DataGridLinkButton" Then
CType(wc, LinkButton).Text = "[" & CType(wc, LinkButton).Text & "]"
Else
CType(wc, Label).Text = "Página " & CType(wc, Label).Text
End If
Next
'Botão próximo
lt = New Literal()
lt.Text = " "
lnk = New LinkButton()
lnk.Text = "Proximo"
AddHandler lnk.Click, AddressOf proximo
pager.Controls.Add(lt)
pager.Controls.Add(lnk)
'Botão anterior
lt = New Literal()
lt.Text = " "
lnk = New LinkButton()
lnk.Text = "Anterior"
AddHandler lnk.Click, AddressOf anterior
pager.Controls.AddAt(0, lnk)
pager.Controls.AddAt(1, lt)
End if
Podemos ainda inserir uma verificação na criação
dos botões anterior e próximo : Se estivermos na primeira página,
o anterior não deve ser criado, na última página, o próximo
não deve ser criado. Basta a inserção de alguns IFs :
Dim wc As WebControl
Dim cnt As Integer
Dim pager As TableCell
Dim lnk As LinkButton
Dim lt As Literal
If e.Item.ItemType = ListItemType.Pager Then
pager = e.Item.Controls(0)
For cnt = 0 To pager.Controls.Count - 1 Step 2
wc = pager.Controls(cnt)
If wc.GetType.ToString() = "System.Web.UI.WebControls.DataGridLinkButton" Then
CType(wc, LinkButton).Text = "[" & CType(wc, LinkButton).Text & "]"
Else
CType(wc, Label).Text = "Página " & CType(wc, Label).Text
End If
Next
If DG.CurrentPageIndex < DG.PageCount - 1 Then
lt = New Literal()
lt.Text = " "
lnk = New LinkButton()
lnk.Text = "Proximo"
AddHandler lnk.Click, AddressOf proximo
pager.Controls.Add(lt)
pager.Controls.Add(lnk)
End If
If DG.CurrentPageIndex > 0 Then
lt = New Literal()
lt.Text = " "
lnk = New LinkButton()
lnk.Text = "Anterior"
AddHandler lnk.Click, AddressOf anterior
pager.Controls.AddAt(0, lnk)
pager.Controls.AddAt(1, lt)
End If
End if
Sem muitas novidades, os IFs checam os valores do CurrentPageIndex comparando-o com o pagecount ou com 0 para decidir se deve-se ou não mostrar os botões próximo e anterior.
Neste ponto realmente já conseguimos uma grande personalização do objeto de paginação da grid, mas vamos avançar um pouco mais, seria possível inserirmos uma textbox com um botão para que o usuário digite o número da página para a qual deseja ir ?
Nesse caso o ideal seria inserirmos em uma célula separada, para podermos controlar a separação entre os botões de navegação e a textbox que iremos criar. Então criaremos 3 novos objetos : Uma nova célula, uma nova textbox e um novo botão.
Não vamos, porém, inserir a nova célula dentro do pager. Vamos sim inserir a nova célula ao lado do pager, que já é uma célula. A linha do pager, que tinha apenas uma célula, passará a ter duas. Veja como fica o código final :
Dim wc As WebControl
Dim cnt As Integer
Dim pager As TableCell
Dim lnk As LinkButton
Dim lt As Literal
Dim tc As TableCell
Dim txt As TextBox
Dim btn As Button
If e.Item.ItemType = ListItemType.Pager Then
pager = e.Item.Controls(0)
For cnt = 0 To pager.Controls.Count - 1 Step 2
wc = pager.Controls(cnt)
If wc.GetType.ToString() = "System.Web.UI.WebControls.DataGridLinkButton" Then
CType(wc, LinkButton).Text = "[" & CType(wc, LinkButton).Text & "]"
Else
CType(wc, Label).Text = "Página " & CType(wc, Label).Text
End If
Next
If DG.CurrentPageIndex < DG.PageCount - 1 Then
lt = New Literal()
lt.Text = " "
lnk = New LinkButton()
lnk.Text = "Proximo"
AddHandler lnk.Click, AddressOf proximo
pager.Controls.Add(lt)
pager.Controls.Add(lnk)
End If
If DG.CurrentPageIndex > 0 Then
lt = New Literal()
lt.Text = " "
lnk = New LinkButton()
lnk.Text = "Anterior"
AddHandler lnk.Click, AddressOf anterior
pager.Controls.AddAt(0, lnk)
pager.Controls.AddAt(1, lt)
End If
tc = New TableCell()
txt = New TextBox()
btn = New Button()
txt.ID = "txtpg"
AddHandler btn.Click, AddressOf irpara
btn.Text = "Ir para"
tc.Controls.Add(txt)
tc.Controls.Add(btn)
CType(e.Item.Controls(0), TableCell).ColumnSpan -= 1
e.Item.Controls.Add(tc)
End If
Como podem observar pelo código adicionei um tratador de evento para o botão, chamei a sub de "irpara", então temos agora que montar essa sub. Nela precisaremos recuperar o valor da textbox que criamos dinamicamente no código acima. Não podemos recuperar diretamente, o método findcontrol também não funciona, então a solução que utilizei foi procurar o valor dentro da coleção request.form, o que nem ao menos pode ser feito diretamente, pois apesar de termos dado o ID txtpg, o datagrid altera essa id quando envia o controle para o client. Assim sendo temos que procurar na coleção forms um item cujo nome contenha a string "txtpg". Encontrando, o resto é fácil, basta utilizar o valor para atualizar a propriedade currentpageindex.
Veja o código :
Sub irpara(ByVal sender As Object, ByVal e As System.EventArgs)
Dim a As Integer
Dim k As String
For a = 0 To Request.Form.Keys.Count - 1
If Request.Form.Keys(a).IndexOf("txtpg") <> -1 Then
k = Request.Form.Keys(a)
Exit For
End If
Next
DG.CurrentPageIndex = Request.Form(k) - 1
carregagrid()
End Sub
Com este exemplo da personalização do pager temos uma excelente
demonstração de como os WebControls, e o DataGrid em particular,
são altamente personalizáveis.
© Búfalo Informática,
Treinamento e Consultoria -
Rua Álvaro Alvim, 37 Sala 920 • Cinelândia • Rio de Janeiro • RJ
Tel.: (21)2262-1368 • e-Mail: contato@bufaloinfo.com.br