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?
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.