0

I have a panel with a form that has a drop down list with values 1-10. When a button on the panel is pressed, that panel is made invisible and a second made visible. On the second panel I have rows of controls being generated dynamically. The number of rows is determined by the selecteditem on the drop down list.

My problem is that when I want to carry out validation and then storing of the values of the contents of controls that are dynamically created, the controls are removed.

I understand this is to do with the lifecycle of the page and the persistence of the dynamically created controls but I have no idea to get round the problem. I have read many other similar questions on here and few have working examples of who to solve this so I am none the wiser. This includes suggestions that the dynamically created controls need to be created on pageload or pageinit, how can this be since we don't know how many to make?

To recap: these controls are NOT addedd when the page loads, these controls are only added AFTER a user has pressed a button. We don't know how many controls to make until the user has selected how many they want.

My code so far:

Partial Class View
Inherits SeatPlannerModuleBase
Implements IActionable
Dim valid As String = "success"

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load, Me.Load
    Try

        Dim n As Integer = 0

        ' now, create n TextBoxes, adding them to the PlaceHolder TextBoxesHere
        For i As Integer = 0 To n - 1
            res_Placeholder.Controls.Add(New Label())
            booking_Placeholder.Controls.Add(New Label())

            title_Placeholder.Controls.Add(New TextBox())
            firstname_Placeholder.Controls.Add(New TextBox())
            surname_Placeholder.Controls.Add(New TextBox())
            ticketNum_Placeholder.Controls.Add(New TextBox())

        Next

        ' now, set the Text property of each TextBox
        IterateThroughBooking(Me)
        IterateThroughReservation(Me)
        IterateThroughTitle(Me)
        IterateThroughFirstname(Me)
        IterateThroughSurname(Me)
        IterateThroughTicketNum(Me)

        If Not Page.IsPostBack Then

        End If

    Catch exc As Exception        'Module failed to load
        ProcessModuleLoadException(Me, exc)
    End Try
End Sub

Protected Sub IterateThroughTitle(ByVal parent As Control)
    Dim count As Integer = 1

    For Each c As Control In title_Placeholder.Controls
        If c.[GetType]().ToString().Equals("System.Web.UI.WebControls.TextBox") AndAlso c.ID Is Nothing Then
            'DirectCast(c, TextBox).Text = "TextBox_Title " + count.ToString()
            DirectCast(c, TextBox).ID = "TextBox_Title_" + count.ToString()
            DirectCast(c, TextBox).CssClass = "DYN_TextBox"
            count += 1
        End If

        If c.Controls.Count > 0 Then
            IterateThroughTitle(c)
        End If
    Next
End Sub

Protected Sub CreateTextBoxes()

    Dim n As Integer = number_of_tickets_Ddl.SelectedValue

    ' now, create n TextBoxes, adding them to the PlaceHolder TextBoxesHere
    For i As Integer = 0 To n - 1
        res_Placeholder.Controls.Add(New Label())
        booking_Placeholder.Controls.Add(New Label())

        title_Placeholder.Controls.Add(New TextBox())
        firstname_Placeholder.Controls.Add(New TextBox())
        surname_Placeholder.Controls.Add(New TextBox())
        ticketNum_Placeholder.Controls.Add(New TextBox())

    Next

    ' now, set the Text property of each TextBox
    IterateThroughBooking(Me)
    IterateThroughReservation(Me)
    IterateThroughTitle(Me)
    IterateThroughFirstname(Me)
    IterateThroughSurname(Me)
    IterateThroughTicketNum(Me)

    Retreive_first_row()

End Sub

Protected Sub next_submit_Btn_Click(ByVal sender As Object, ByVal e As EventArgs) Handles next_submit_Btn.Click

    Step1_Pnl.Visible = False
    Step2_Pnl.Visible = True
    CreateTextBoxes()
    Button1.Attributes.Add("OnClick", "validate_step2(); return false;")

End Sub

Protected Sub next_submit2_Btn_Click(ByVal sender As Object, ByVal e As EventArgs) Handles next_submit2_Btn.Click

    step2_error_Lbl.Text = CType(Me.FindControl("TextBox_Title_2"), TextBox).Text

End Sub

End Class       
Agamemnon
  • 587
  • 2
  • 15
  • 44
  • 2
    Can you please narrow down your code to the relevant code only. It will be easier to fix it. – Amiram Korach Aug 20 '12 at 09:41
  • The problem is that I take the number the user selects in the dropdown, create that many rows of textboxes. When I try to save what they have enter in these textboxes I get an "Object reference not set to an instance of an object" error. I think this is because, as soon as the button that tries to retreive the values from the textboxes is pressed, the boxes dissapear. How do I get the values out of those textboxes? – Agamemnon Aug 20 '12 at 09:47
  • Call `CreateTextBoxes` in `Page_Load` too. – Amiram Korach Aug 20 '12 at 09:49
  • How will I know how many to create? It could be 1 row of 5 textboxes or it could be 10 rows. This is only decided after the user has selected and submitted a button. – Agamemnon Aug 20 '12 at 10:02
  • You can check `number_of_tickets_Ddl.SelectedValue`, don't you? Try that and see. Just add the call in `Page_Load`. Put a default value of "0" in the dropdown so you won't create anything if nothing was chosen yet. – Amiram Korach Aug 20 '12 at 10:04
  • Ok, I have tried putting a call to the subroutine 'CreateTextBoxes()' in the Page_Init but when I test the page I get an "Object reference not set to an instance of an object" error. If I set the value of how many textboxes should be rendered as a variable instead of taking the value from the DLL I get: "Multiple controls with the same ID 'BookLabel_1' were found. FindControl requires that controls have unique IDs" error. BookLabel_ is the first control that gets created. – Agamemnon Aug 20 '12 at 10:23
  • 1. Put it in `Page_Load`. 2. Check you're not using this method twice in the page. – Amiram Korach Aug 20 '12 at 10:43
  • I moved this into Page_Load, I am using this Sub once in the Page_Load (as per suggestion) and then once in the button that needs to create the rows of controls. I still get the "Multiple controls with the same ID 'BookLabel_1' were found. FindControl requires that controls have unique IDs" error. – Agamemnon Aug 20 '12 at 10:54
  • 1
    Edit your code with the latest changes and delete all the irrelevant code. This way more people might look at it and help you. – Amiram Korach Aug 20 '12 at 11:02
  • Ok the code is heavily cut down and has the addition to the Page_load as suggested. If I leave the number of controls to be added in the pag_load as 0 then nothing appears to happen at all. I am unable to retreive the values from the controls after they have been created and the button that treis to retreive them has been pressed. Controls also dissapear (as they did before). If I set a number for the rows of controls to be created then I recieve the error about multiple contol IDs. – Agamemnon Aug 20 '12 at 11:16

1 Answers1

0

The dynamic created controls don't persist after postback, you have to recreate them everytime, it's a technological restriction. To know how many controls create, you could save a variable in session/viewstate/whatever and if you name them just like the previous state, the viewstate will be recovered though.

Check these links for more information:

http://weblogs.asp.net/infinitiesloop/archive/2006/08/25/TRULY-Understanding-Dynamic-Controls-_2800_Part-1_2900_.aspx

ASP.NET dynamically created controls and Postback

Community
  • 1
  • 1