Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Dynamically adding controls to form based on type

Status
Not open for further replies.

raphael232

Programmer
Jun 9, 2006
51
GB
Hi i am trying to create a dynamic web form which displays controls based on information stored in the database.

I have a formview control on my page and a repeater within that:

Code:
<asp:FormView ID="FormView1" runat="server" DataSourceID="ObjectDataSource1" DefaultMode="Insert">
    <InsertItemTemplate>
        <table>
            <asp:Repeater ID="Repeater1" runat="server">
	        <ItemTemplate>
                    <tr>
                        <td class="TableHeader"><%# Eval("AttributeName") %>: CONTROL HERE</td>
		    </tr>
                </ItemTemplate>
            </asp:Repeater>
        </table>
        <asp:Button ID="btnInsert" CommandName="Insert" runat="server" Text="Insert" />
    </InsertItemTemplate>
</asp:FormView>
/code]

I figured i could bind the data from the database to my repeater with the Page_Load event handler:

[code]
Dim attributesAdapter As New KITTableAdapters.AttributesTableAdapter
Dim Repeater1 As Repeater = CType(FormView1.FindControl("Repeater1"), Repeater)

Repeater1.DataSource = attributesAdapter.GetAttributesBySectionID(sectionID)
Repeater1.DataBind()

This works fine so far but notice i have not displayed the control on the page. Here's the structure for the attributes table:

- ID
- SectionID
- AttributeName
- AttributeType

What i need to do is add the control to the page based on the AttributeType value ie if AttributeType = "String" i would need to add a text box or if it equals "Image" i would need to add the image control.

I'm not too sure where to go on this as this is the most complicated thing i have had to do in asp.net so far.

Appreciate if someone could help. Thanks
 
This article will help you immensely.




It creates only one kind of control in the sample code, but what you'd do is read in your attributes data, then loop through it and create template columns that way.

switch(AttributeType)
case "String":
// Create text box
break;
case "Image":
// Create image control
break;


etc.


Comment here if you need more help after you get started.
 
The key point in using dynamically created controls, is that they have to be recreated each time there is a post back. In order for the viewstate to work correctly with dynamic controls, use the Page_Init method of the page to add them.

Jim
 
Hi cheers i found the tutorial relatively easy to follow. One thing i did not like though was having to add the event handler to display the data from the dataset.

Here's an example of what i did:

Code:
Sub InstantiateIn(ByVal container As Control) _
    Implements ITemplate.InstantiateIn

    Dim lc As New Literal()

    lc.Text = "<tr><td>"
    AddHandler lc.DataBinding, AddressOf TemplateControl_DataBinding
    container.Controls.Add(lc)
End Sub

Private Sub TemplateControl_DataBinding(ByVal sender As Object, ByVal e As System.EventArgs)
    Dim lc As Literal
    Dim container As RepeaterItem

    lc = CType(sender, Literal)
    container = CType(lc.NamingContainer, RepeaterItem)
    lc.Text &= DataBinder.Eval(container.DataItem, "AttributeName")
    lc.Text &= "</td></tr>"
End Sub

It seems alot of extra work just to display the attributename. I was wondering (since the article was published ages ago) if there is now a better solution so i don't have to add the extra event handler. I Know i'm being fussy but i love my pretty code :).
 
Just discovered a further problem. Now i'm trying to add a textbox (as an example but could be anything depending on my attributetype) control within the literal. One small problem, where do i start to do this?

Appreciate your help once more. Thanks
 
You can have text within the literal, but it's more appropriate to have a PlaceHolder right next to it to house the dynamically created control. You'd add your newly created control by calling Controls.Add().
 
A futher follow up to say i have solved the above problem by doing:

Code:
Sub InstantiateIn(ByVal container As Control) _
    Implements ITemplate.InstantiateIn

    Dim lc As New Literal()
    Dim txtControl As New TextBox()
    Dim lc2 As New Literal()

    lc.Text = "<tr><td colspan=""2"" class=""TableHeader"">"
    AddHandler lc.DataBinding, AddressOf TemplateLiteralControl_DataBinding
    txtControl.Text = "Value"
    lc2.Text = "</td></tr>"

    container.Controls.Add(lc)
    container.Controls.Add(txtControl)
    container.Controls.Add(lc2)

    itemCount += 1
End Sub

Private Sub TemplateLiteralControl_DataBinding(ByVal sender As Object, ByVal e As System.EventArgs)
    Dim lc As Literal
    Dim container As RepeaterItem

    lc = CType(sender, Literal)
    container = CType(lc.NamingContainer, RepeaterItem)
    lc.Text &= DataBinder.Eval(container.DataItem, "AttributeName")
    lc.Text &= "</td></tr>"
    lc.Text &= "<tr><td colspan=""2"" class=""TableContent"">"
End Sub

but this possesses the problem i encountered above if i can't get the AttributeType value from the datarow without having to add an event handler how do i know which control to add???

Sorry about the multiple replies but you can't delete posts and i'm not going to be defeated on this one :).
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top