Search code examples
asp.netvb.netpanel

Place dynamically created controls in a 2 or 3 column display


I've managed to successfully create a panel with dynamically created label and textbox created controls and now I need to be able to place them in a 1 (easy), 2 or 3 column display within the panel (based on user selection). This is the code that generates the controls"

If MydataSet.Tables(0).Rows.Count > 0 Then
    For Each MyDataRow As DataRow In MydataSet.Tables(0).Rows
        Me.CreateLabel("lblDynamic_" & MyDataRow("ID"), MyDataRow("Title"))

        Me.CreateTextBox("txtDynamic_" & MyDataRow("ID"))
    Next
End If

CreateLabel and CreateTextbox code:

Private Sub CreateTextBox(id As String)
    Dim txt As New TextBox()
    txt.ID = id
    Panel_AdditionalData.Controls.Add(txt)

    Dim lt As New Literal()
    lt.Text = "<br />"
    Panel_AdditionalData.Controls.Add(lt)
End Sub

Private Sub CreateLabel(id As String, value As String)
    Dim lbl As New Label()
    lbl.ID = id
    lbl.Text = value
    lbl.CssClass = "label"
    Panel_AdditionalData.Controls.Add(lbl)

    Dim lt As New Literal()
    lt.Text = "<br />"
    Panel_AdditionalData.Controls.Add(lt)
End Sub

Obviously there is more code to manage postbacks and retrieving inputted data, but for the purposes of layout posting that code isn't relevant.

I retrieve the user defined data fields from the database and use that information to create each control. Creating each control in a single column is easy, just add the control, no problem. I've already done that. However, creating a multi-column layout is proving to be difficult and everything I've tried thus far has failed. Anyone have any suggestions?


Solution

  • As my research and the comments/answers posted in response to my question point out, there are a myriad of ways one can get the job done. Given my time constraints and the need to get the infrastructure in place to provide this functionality to my users, I went with the "quick and relatively" easy method.

    This is what I went with:

    ; defined in the page class
    Shared ColumnCount As Integer = 1
    
    ' class initiated with the users layout preferences and other user information
    ' MyUserPrefrence.NumberOfColumns  
    
    ' defined in the page load event
    Dim MydataSet As New DataSet ' Data field information loaded from database
    Dim MyHTMLTable As New HtmlTable
    Dim MyTableRow As New HtmlTableRow
    Dim MyTableCell As New HtmlTableCell
    
    If MydataSet.Tables(0).Rows.Count > 0 Then
        For Each MyDataRow As DataRow In MydataSet.Tables(0).Rows
            MyTableCell = New HtmlTableCell
    
            Dim lbl As New Label()
            lbl.ID = ID
            lbl.Text = MyDataRow("Title")
            lbl.CssClass = "label"
            Dim lt As New Literal()
            lt.Text = "<br />"
    
            MyTableCell.Controls.Add(lbl)
            MyTableCell.Controls.Add(lt)
    
            Dim txt As New TextBox()
            txt.ID = MyDataRow("ID")
            lt = New Literal()
            lt.Text = "<br />"
            MyTableCell.Controls.Add(txt)
            MyTableCell.Controls.Add(lt)
    
    
            If ColumnCount < MyUserPrefrence.NumberOfColumns Then
                MyTableRow.Cells.Add(MyTableCell)
                ColumnCount += 1
            Else
                MyTableRow.Cells.Add(MyTableCell)
                MyHTMLTable.Rows.Add(MyTableRow)
                MyTableRow = New HtmlTableRow
                ColumnCount = 1
            End If
    
        Next
        MyHTMLTable.Rows.Add(MyTableRow)
        Panel_AdditionalData.Controls.Add(MyHTMLTable)
        ColumnCount = 1 'Reset colum count to 1
    

    The page that contains the dynamic controls will not be posted back to the server via the usual post back method but rather by an ajax method and json data posted to a web method in the code behind to avoid any issues with maintaining the dynamic fields on a post back. I have been gradually going to this method of posting back data as it is (apparently) very efficient and avoids screen refreshing and I am able to provide immediate feedback to the user in real time a lot more cleanly. I find that very appealing. In this particular instance it also solves the problem of linking the data to a particular entity whether it is a new or existing (edited) entity.