Friday, 15 July 2011

Dynamic Repeater ItemTemplate: Retrieving your entity on DataBinding

I am building a survey application.

The collection of questions will be bound to a repeater.

Each item in the Repeater will need to have its content dynamically constructed based on in-code logic ... for example the type of question and the answer options.

So i read this article on how to Create Web Server Control Templates Dynamically.

This was a good start.

The only major difference for me was that i wasn't binding directly to a table retrieved from a database containing columns but instead a custom EntitySpaces entity (could be any other in-house business object though).

The thing i struggled to find examples of was how to retrieve the entity during the data binding, so that you can actually tailor the contents of the Template based on the properties of the entity.

In short, the way to do it is to make use of the DataItem property of the RepeaterItem class (this article gave it away for me)

This is how its done:

 Public Class SurveyQuestionTemplate
    Implements ITemplate

    Dim templateType As ListItemType
    Dim question As SurveyQuestion

    Sub New(ByVal type As ListItemType)
        templateType = type
    End Sub

    Sub InstantiateIn(ByVal container As Control) Implements ITemplate.InstantiateIn
        Dim lc As New Literal()

        Select Case templateType

            Case ListItemType.Header
                lc.Text = "<div id='header'>Survey Questions</div>"

            Case ListItemType.Item
                ' Instead of rendering static HTML, create dynamic controls within a handler to the DataBinding event 
                AddHandler lc.DataBinding, AddressOf SurveyQuestionTemplate_DataBinding

            Case ListItemType.AlternatingItem
                ' Instead of rendering static HTML, create dynamic controls within a handler to the DataBinding event 
                AddHandler lc.DataBinding, AddressOf SurveyQuestionTemplate_DataBinding

            Case ListItemType.Footer
                lc.Text = "<div id='footer'>End Survey Questions</div>"
        End Select

        container.Controls.Add(lc)
    End Sub

    Private Sub SurveyQuestionTemplate_DataBinding(ByVal sender As Object, ByVal e As System.EventArgs)
        'Get a reference to the template item
        Dim litCntrl As Literal
        litCntrl = CType(sender, Literal)

        'Get the naming container
        Dim container As RepeaterItem
        container = CType(litCntrl.NamingContainer, RepeaterItem)

        'Set the dynamic content you want
        litCntrl.Text = GenerateRowContent(container)
    End Sub

    Function GenerateRowContent(container As RepeaterItem) As String
        Dim html As String = ""

        'Retrieve the Question entity
        question = CType(container.DataItem, SurveyQuestion)
       
        'I now have my Question entity which i can use and inspect as necessary
        html = GenerateHTMLForQuestion(question)
        Return html
    End Function
End Class

No comments:

Post a Comment