|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Retrieving Values from Dynamically Created Controlsdo was cycle through the controls collection of the container, but I can't seem to figure out where the controls are contained when I am adding them to table cells (of table rows of an ASP.NET TABLE control). Basically, I have a web form that contains some fields, and then a dropdownlist where the user says how many rows of input they need (up to a max of 15). On the dropdownlist's _SelectedIndexChanged event, I make the table visible and only add as many rows as I need. Each row contains 6 columns, and each column contains 1 control - either a textbox or a dropdownlist. The code below works perfectly as far as displaying the input table with desired controls, and all the controls seem to work as expected. The problem is that I can not seem to be able to retrieve the values later (when the submit button is pushed). The table's control collection is empty, and the table's rows collection always seems empty (and rows count is zero) when debugging at run time even though I can see the table populated with the correct number of rows and I can populate the textboxes and dropdownlists as expected in the browser before I submit. I was expecting the programmatically defined controls to be members of the controls collection for the table itself, the row's controls collection, and/or the row's cells' collection, but as mentioned above the rows count always appears as zero when I run this, and can not find the visible controls contained anywhere. The initial table is simply defined on the form as: <p> <asp:Table ID="tblResources" runat="server" BorderColor="Black" BorderStyle="Solid" BorderWidth="1px" GridLines="Both" Visible="False" style="line-height: normal"> </asp:Table> </p> It is initially hidden, and then when the user selects the number of rows to display, it made visible and populated with rows, cells and controls using the following code: Protected Sub ddlNbrResources_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ddlNbrResources.SelectedIndexChanged Dim rowCnt As Integer Dim rowCtr As Integer Dim cellCnt As Integer Dim cellCtr As Integer tblResources.Visible = True rowCnt = CInt(ddlNbrResources.SelectedValue) 'User specified # of rows cellCnt = 6 'Fixed # of table columns For rowCtr = 1 To rowCnt Dim tRow As New TableRow() For cellCtr = 1 To cellCnt Dim tCell As New TableCell() Select Case cellCtr Case 1 Dim tbResName As TextBox = New TextBox() tbResName.ID = "tbResName" & CStr(rowCtr) tbResName.Width = 140 tCell.Controls.Add(tbResName) Case 2 Dim tbResID As TextBox = New TextBox() tbResID.ID = "tbResID" & CStr(rowCtr) tbResID.Width = 50 tbResID.MaxLength = 6 tCell.Controls.Add(tbResID) Case 3 Dim ddlResCountry As DropDownList = New DropDownList() ddlResCountry.ID = "ddlResCountry" & CStr(rowCtr) ddlResCountry.Items.Add("") ddlResCountry.Items.Add("Asia / Pacific") ddlResCountry.Items.Add("Canada") ddlResCountry.Items.Add("EMEA") ddlResCountry.Items.Add("Latin America") ddlResCountry.Items.Add("United States") tCell.Controls.Add(ddlResCountry) Case 4 Dim tbResFrom As TextBox = New TextBox() tbResFrom.ID = "tbResFrom" & CStr(rowCtr) tbResFrom.Width = 65 tCell.Controls.Add(tbResFrom) Case 5 Dim tbResTo As TextBox = New TextBox() tbResTo.ID = "tbResTo" & CStr(rowCtr) tbResTo.Width = 65 tCell.Controls.Add(tbResTo) Case 6 Dim ddlResAppOrg As DropDownList = New DropDownList() ddlResAppOrg.ID = "ddlResAppOrg" & CStr(rowCtr) ddlResAppOrg.Items.Add("") ddlResAppOrg.Items.Add("Apps") ddlResAppOrg.Items.Add("BPO") ddlResAppOrg.Items.Add("ITO") ddlResAppOrg.Items.Add("EA") ddlResAppOrg.Items.Add("SA") ddlResAppOrg.Items.Add("BD") tCell.Controls.Add(ddlResAppOrg) End If Case Else tCell.Text = "oops - should not be here" End Select ' Add new TableCell object to row. tRow.Cells.Add(tCell) Next ' Add new row to table. tblResources.Rows.Add(tRow) Next End Sub All the above works great, but when my submit button's click event later occurs, I can't seem to find a way to cycle through the appropriate controls collection to get the user-specific values. I try something like (just to build a string with the control IDs so I know I am finding them - this does not yet attempt to use the controls values yet): Dim i, j As Integer Dim sb As New StringBuilder 'Cycle through each row used in the resource table Dim ctrl As Control For i = 0 To CInt(ddlNbrResources.SelectedValue) - 1 For j = 0 To 5 For Each ctrl In tblResources.Rows(i).Cells(j).Controls sb.Append(ctrl.ID.ToString) Next Next Next But when I run the above, the tblResources.Rows.Count is zero, the tblResources.Controls collection appears empty, and the tblResources.Rows.Controls collection appears empty even though I can see them all on the form just fine and interact with them as expected. Where/how can I find the values of the controls programmatically defined as above at run time??? Sorry for the long post - but this has been eating at me for 3 days now and I wanted to give you as much detail as possible to help me find a solution (a solution that does not just give up and predefines the entire table with all 25 possible rows). As always, thanks for all your assistance - I've always gotten great feedback from this group, and look forward to your help on this issue! Hi,
Based on my understanding, you're trying to create dynamic count of table rows which have predefined server controls; and you want to obtain the values user have input in them. However, you're seeing that the controls doesn't get recreated upon postback. This is the expected behavior, remember ASP.NET is stateless, the control hierarchy needs to be re-created upon every postback at server-side. For controls added dynamically, you need a way to re-create them at server-side again. For more information, please refer to following KB article: #HOW TO: Dynamically Create Controls in ASP.NET with Visual Basic .NET http://support.microsoft.com/kb/317515 However, for your specific requirement, this is not the best way to do this by doing this yourself. You can use the Repeater control to create those dynamic controls for you, and use it to read the values after that: <asp:Repeater ID="repeater1" runat="server"> <HeaderTemplate> <table> </HeaderTemplate> <ItemTemplate> <tr> <td> <asp:TextBox ID="tbResName" runat="server"></asp:TextBox></td> <td> <asp:TextBox ID="tbResID" runat="server"></asp:TextBox></td> <td> <asp:DropDownList ID="ddlResCountry" runat="server"> <asp:ListItem></asp:ListItem> <asp:ListItem>Asia / Pacific</asp:ListItem> <asp:ListItem>Canada</asp:ListItem> <asp:ListItem>EMEA</asp:ListItem> <asp:ListItem>Latin America</asp:ListItem> <asp:ListItem>United States</asp:ListItem> </asp:DropDownList> </td> <td><asp:TextBox ID="tbResFrom" runat="server"></asp:TextBox></td> <td><asp:TextBox ID="tbResTo" runat="server"></asp:TextBox></td> <td> <asp:DropDownList ID="ddlResAppOrg" runat="server"> <asp:ListItem></asp:ListItem> <asp:ListItem>Apps</asp:ListItem> <asp:ListItem>BPO</asp:ListItem> <asp:ListItem>ITO</asp:ListItem> <asp:ListItem>EA</asp:ListItem> <asp:ListItem>SA</asp:ListItem> <asp:ListItem>BD</asp:ListItem> </asp:DropDownList> </td> </tr> </ItemTemplate> <FooterTemplate> </table> </FooterTemplate> </asp:Repeater> Normally a Repeater control will be bound to a data source and you can use data binding expression in the template to show bound data. Since here you're only want to show some static controls, just the row count needs to repeated, we can use an dumb array as the data source, --just the size is the value selected by user: rowCnt = CInt(ddlNbrResources.SelectedValue) 'User specified # of rows() Dim dummy(rowCnt - 1) As Integer repeater1.DataSource = dummy repeater1.DataBind() And here's how you can retrieve the values input by the user: Protected Sub button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button1.Click For i As Integer = 0 To repeater1.Items.Count - 1 Dim tbResName As TextBox = CType(repeater1.Items(i).FindControl("tbResName"), TextBox) ' You can use FindControl to find those controls inside a RepeaterItem Next End Sub Hope this helps. Sincerely, Walter Wang (waw***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. If you are using Outlook Express, please make sure you clear the check box "Tools/Options/Read: Get 300 headers at a time" to see your reply promptly. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Walter - thank you very much for the quick response, and for giving me the
option of pursuing my original way via the link, and the better way using the Repeater control. After a cursory review of the KB article I definitely want to pursue use of the repeater. Again, thanks, and have a great day! Show quoteHide quote "Walter Wang [MSFT]" wrote: > Hi, > > Based on my understanding, you're trying to create dynamic count of table > rows which have predefined server controls; and you want to obtain the > values user have input in them. However, you're seeing that the controls > doesn't get recreated upon postback. > > This is the expected behavior, remember ASP.NET is stateless, the control > hierarchy needs to be re-created upon every postback at server-side. For > controls added dynamically, you need a way to re-create them at server-side > again. For more information, please refer to following KB article: > > #HOW TO: Dynamically Create Controls in ASP.NET with Visual Basic .NET > http://support.microsoft.com/kb/317515 > > > > However, for your specific requirement, this is not the best way to do this > by doing this yourself. You can use the Repeater control to create those > dynamic controls for you, and use it to read the values after that: > > <asp:Repeater ID="repeater1" runat="server"> > <HeaderTemplate> > <table> > </HeaderTemplate> > <ItemTemplate> > <tr> > <td> > <asp:TextBox ID="tbResName" > runat="server"></asp:TextBox></td> > <td> > <asp:TextBox ID="tbResID" > runat="server"></asp:TextBox></td> > <td> > <asp:DropDownList ID="ddlResCountry" > runat="server"> > <asp:ListItem></asp:ListItem> > <asp:ListItem>Asia / > Pacific</asp:ListItem> > <asp:ListItem>Canada</asp:ListItem> > <asp:ListItem>EMEA</asp:ListItem> > <asp:ListItem>Latin > America</asp:ListItem> > <asp:ListItem>United > States</asp:ListItem> > </asp:DropDownList> > </td> > <td><asp:TextBox ID="tbResFrom" > runat="server"></asp:TextBox></td> > <td><asp:TextBox ID="tbResTo" > runat="server"></asp:TextBox></td> > <td> > <asp:DropDownList ID="ddlResAppOrg" > runat="server"> > <asp:ListItem></asp:ListItem> > <asp:ListItem>Apps</asp:ListItem> > <asp:ListItem>BPO</asp:ListItem> > <asp:ListItem>ITO</asp:ListItem> > <asp:ListItem>EA</asp:ListItem> > <asp:ListItem>SA</asp:ListItem> > <asp:ListItem>BD</asp:ListItem> > </asp:DropDownList> > </td> > </tr> > </ItemTemplate> > <FooterTemplate> > </table> > </FooterTemplate> > </asp:Repeater> > > > > Normally a Repeater control will be bound to a data source and you can use > data binding expression in the template to show bound data. Since here > you're only want to show some static controls, just the row count needs to > repeated, we can use an dumb array as the data source, --just the size is > the value selected by user: > > rowCnt = CInt(ddlNbrResources.SelectedValue) 'User specified # of > rows() > > Dim dummy(rowCnt - 1) As Integer > repeater1.DataSource = dummy > repeater1.DataBind() > > > And here's how you can retrieve the values input by the user: > > Protected Sub button1_Click(ByVal sender As Object, ByVal e As > System.EventArgs) Handles button1.Click > For i As Integer = 0 To repeater1.Items.Count - 1 > Dim tbResName As TextBox = > CType(repeater1.Items(i).FindControl("tbResName"), TextBox) > ' You can use FindControl to find those controls inside a > RepeaterItem > Next > End Sub > > > Hope this helps. > > > Sincerely, > Walter Wang (waw***@online.microsoft.com, remove 'online.') > Microsoft Online Community Support > > ================================================== > Get notification to my posts through email? Please refer to > http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif > ications. If you are using Outlook Express, please make sure you clear the > check box "Tools/Options/Read: Get 300 headers at a time" to see your reply > promptly. > > Note: The MSDN Managed Newsgroup support offering is for non-urgent issues > where an initial response from the community or a Microsoft Support > Engineer within 1 business day is acceptable. Please note that each follow > up response may take approximately 2 business days as the support > professional working with you may need further investigation to reach the > most efficient resolution. The offering is not appropriate for situations > that require urgent, real-time or phone-based interactions or complex > project analysis and dump analysis issues. Issues of this nature are best > handled working with a dedicated Microsoft Support Engineer by contacting > Microsoft Customer Support Services (CSS) at > http://msdn.microsoft.com/subscriptions/support/default.aspx. > ================================================== > > This posting is provided "AS IS" with no warranties, and confers no rights. > >
business layer, data access layer , presentation layer for asp.net using C#.net
Convert OEM to Unicode Dynamically load a form Raising an event from a user control Changing file name Determine if app fails... Detect Multiple Keystrokes? Inherited form Name from Base Borderless Form How to manage a exception in a Aplications |
|||||||||||||||||||||||