geeky stuff: repeaters

A programação declarativa é uma das modas actuais mas como ainda não estou a usar WPF e as (supostas) maravilhas do XAML limito-me a aproveitar os controles de ASP.Net que já existem desde a versão 1.0.

Um dos controles que mais gosto é o repeater pela facilidade com que multiplicamos texto e pelo facto de já incluir alguma flexibilidade no que diz respeito aquelas situações habituais quando estamos numa de multiplicar texto nomedamente: ItemTemplate, AlternatingItemTemplate, FooterTemplate, HeaderTemplate e SeparatorTemplate.

Mesmo assim por vezes surgem situações que levam a que seja necessário um pouco de programação para conseguirmos acomodar os templates às nossas necessidades. Estou a pensar em dois cenários concretos: nested repeaters e repeaters sem valores.

O caso dos nested repeaters é aquele em que por exemplo queremos representar uma relação hierarquica. Temos n registos, mas dentro que cada um desses registos ainda temos mais y que queremos apresentar. A resolução do problema tem 2 partes, uma que diz respeito ao acesso a dados, a outra que diz respeito à atribuição do subconjunto de informação especifico que queremos mostrar no repeater de nivel inferior.

Em relação ao acesso a dados, podemos simplesmente ir buscar os dados da tabela mãe e depois por cada linha dessa tabela ir buscar os outros dados, por exemplo:

    Private Sub InitRptAgrupamentos()

        With rptAgrupamentos
            .DataSource = _competenciasEngine.GetBundles()
            .DataBind()
        End With

    End Sub

    Private Sub rptAgrupamentos_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptAgrupamentos.ItemDataBound

        Dim item As RepeaterItem = e.Item
        Dim rpt As Repeater = CType(item.FindControl("rptCompetencias"), Repeater)
        Dim agrupamento As String = CType(item.DataItem, DataRowView).Item("Name").ToString()

        With rpt
            .DataSource = _competenciasEngine.GetTags(agrupamento)
            .DataBind()
        End With

    End Sub

ou então trazer as 2 tabelas de uma só vez e depois “dizer” qual a relação que tem que ser usada para ir buscar o subconjunto correcto de dados. algo como:


        ds.Tables.Add(dtUtilizadores)
        ds.Tables.Add(dtExperiencias)
        ds.Relations.Add(New DataRelation("Utilizadores_Experiencias", dtUtilizadores.Columns("UserId"), dtExperiencias.Columns("UserId")))

    Private Sub rptUtilizadores_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptUtilizadores.ItemDataBound

        Dim item As RepeaterItem = e.Item
        Dim rptExperiencias As Repeater = CType(item.FindControl("rptExperiencias"), Repeater)

        With rptExperiencias
            .DataSource = CType(item.DataItem, DataRowView).CreateChildView("Utilizadores_Experiencias")
            .DataBind()
        End With
    End Sub

mais informação em: Nesting Repeaters with Hierarchical Data and Server-Binding

A outra situação de não processar o repeater quando não há dados só é relevante se tivermos a usar o HeaderTemplate ou FooterTemplate já que os outros só são processados se realmente houver dados.
Nesse caso a solução passa por verificar antes de o controlo ser renderizado se realmente há dados.

    Protected Sub rptExperiencias_PreRender(ByVal sender As Object, ByVal e As System.EventArgs)

        If CType(sender, Repeater).Items.Count = 0 Then CType(sender, Repeater).Visible = False

    End Sub

Publicado

em

por

Etiquetas:

Comentários

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *