Translate this page now :



»Programação
»Programação.NET
»Banco de Dados
»Webdesign
»Office
» Certificações Microsoft 4
»Treinamentos4
»Programação 4
»Webdesign«
»Office & User Tips«
»Grupos de Usuários
»Células Acadêmicas«
intcontpiada : 118
Scaneando
Você já está cadastrado e participa do grupo de usuários de sua cidade ? Se não, comente o porque.
 
 
Faça um pequeno teste com 10 questões de VB
.:.
Teste seus conhecimentos em Visual Basic, SQL Server e ASP 3.0 com nossas provas on-line
.:.
Aprimore seus conhecimentos em programação com nosso treinamento on-line de lógica de programação
.:.
Veja nosso calendário de treinamentos
Gostou da Página?
Então

para um amigo!
 







Pesquisa personalizada
Pesquisar Dicas:

 






Criando objetos de paginação personalizados na grid

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 (&nbsp). 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 = "&nbsp"
     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 = "&nbsp"
     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 = "&nbsp"
     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 = "&nbsp"
     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 = "&nbsp"
     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 = "&nbsp"
     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.


Dennes Torres
MCSD,MCSE,MCDBA


� Búfalo Informática, Treinamento e Consultoria - Rua Álvaro Alvim, 37 Sala 920 - Cinelândia - Rio de Janeiro / RJ
Tel.: (21)2262-1368 (21) 9240-5134 (21) 9240-7281 e-Mail:
contato@bufaloinfo.com.br