By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,681 Members | 1,775 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,681 IT Pros & Developers. It's quick & easy.

Puzzling behaviour for dynamically added command buttons....

P: n/a
Hi. I have a page with the following html:

__________________________________________________ ________
<h1>Dynamic Controls Test</h1>
<hr />
<asp:TextBox ID="txtProduct1" Text="txtProduct 1" runat="server"></
asp:TextBox>
<asp:Button ID="cmdAddRow" Text="+" AccessKey="+" runat="server" />
<asp:Button ID="cmdSubtractRow" Text="-" AccessKey="+" runat="server" /
>
<asp:PlaceHolder runat="server" id="placeTextBoxes" />
<hr />
<asp:Button ID="cmdPostback" Text="Postback !" runat="server" />
<br />
<asp:label runat="server" id="lblControlList" />
__________________________________________________ ________

and the code

__________________________________________________ ________
Protected Sub Page_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load

If Not IsPostBack Then
'Initial load...
ViewState("FieldCount") = 1
End If
DrawAllRows()
End Sub

Protected Sub cmdAddRow_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles cmdAddRow.Click

ViewState("FieldCount") += 1
placeTextBoxes.Controls.Clear()
DrawAllRows()
End Sub

Protected Sub cmdSubtractRow_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles cmdSubtractRow.Click

ViewState("FieldCount") -= 1
placeTextBoxes.Controls.Clear()
DrawAllRows()
End Sub

Protected Sub cmdPostback_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles cmdPostback.Click

lblControlList.Text = ListAllControls(Page)
End Sub

Private Sub DrawAllRows()

Dim intCounter As Integer
Dim intMaxCount As Integer

intMaxCount = CInt(ViewState("FieldCount"))
If intMaxCount 1 Then
For intCounter = 2 To intMaxCount
AddRowOfControls(intCounter)
Next
End If
lblControlList.Text = ListAllControls(Page)
End Sub

Private Sub AddRowOfControls(ByVal intRowCount As Integer)

Dim litLabel As LiteralControl
Dim txtTextBox As TextBox
Dim cmdAddRow As Button
Dim cmdSubtractRow As Button

litLabel = New LiteralControl
litLabel.Text = "<br>"
placeTextBoxes.Controls.Add(litLabel)

txtTextBox = New TextBox
txtTextBox.Text = "txtProduct " & intRowCount.ToString
placeTextBoxes.Controls.Add(txtTextBox)

cmdAddRow = New Button
cmdAddRow.Text = "+"
AddHandler cmdAddRow.Click, AddressOf cmdAddRow_Click
placeTextBoxes.Controls.Add(cmdAddRow)

cmdSubtractRow = New Button
cmdSubtractRow.Text = "-"
AddHandler cmdSubtractRow.Click, AddressOf cmdSubtractRow_Click
placeTextBoxes.Controls.Add(cmdSubtractRow)
End Sub

Private Function ListAllControls(ByVal objContainter As Control) As
String

Dim strBuilder As New StringBuilder
Dim ctlText As TextBox

For Each ctl As Control In objContainter.Controls
If ctl.Controls.Count 0 Then
strBuilder.Append(ListAllControls(ctl))
Else
If TypeOf ctl Is TextBox Then
ctlText = CType(ctl, TextBox)
strBuilder.Append("<br>")
strBuilder.Append(ctlText.Text)
End If
End If
Next

If Not ctlText Is Nothing Then
ctlText.Dispose()
End If

Return strBuilder.ToString
End Function
__________________________________________________ ________

What could be simpler ? And still.... If I click only the + and the -
buttons which have NOT been created dynamically, everything is just
fine. However, if I click on the newly created buttons, let's say on
the + button, I need TWO clicks - one changes the text in the last
textbox from, say, "txtProduct 5" to "txtProduct 2", and the second
click finally adds a new row and now everything is correct - it adds
"txtProduct 6" and I obtain the list of controls as follows:

txtProduct 1
txtProduct 2
txtProduct 3
txtProduct 4
txtProduct 5
txtProduct 6

What's wrong with this approach ? I'm obviously missing something ! ;-
((

Thank you very much.
Alex

Jun 8 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Hi

That is because ommand buttons clicks are invoked by control ID. When you
recreate controls while handling click event, you create new controls with
new IDs. However, next time on postback the same controls are created with
different IDs. Therefore, if page was generated with recreating controls
command buttons IDs are different.

Try assigning unique IDs to your controls and try not recreating already
existing controls. I.e if you add new line of controls just add it without
clearing existing.

To see your problem replace

strBuilder.Append(ctlText.Text)

with
strBuilder.Append(ctlText.Text + " " + ctlText.UniqueID)

And see how IDs chnage.

yuriy
Hi. I have a page with the following html:

__________________________________________________ ________
<h1>Dynamic Controls Test</h1>
<hr />
<asp:TextBox ID="txtProduct1" Text="txtProduct 1" runat="server"></
asp:TextBox>
<asp:Button ID="cmdAddRow" Text="+" AccessKey="+" runat="server" />
<asp:Button ID="cmdSubtractRow" Text="-" AccessKey="+" runat="server"
/
<asp:PlaceHolder runat="server" id="placeTextBoxes" />
<hr />
<asp:Button ID="cmdPostback" Text="Postback !" runat="server" />
<br />
<asp:label runat="server" id="lblControlList" />
__________________________________________________ ________
and the code

__________________________________________________ ________ Protected
Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles Me.Load

If Not IsPostBack Then
'Initial load...
ViewState("FieldCount") = 1
End If
DrawAllRows()
End Sub
Protected Sub cmdAddRow_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles cmdAddRow.Click

ViewState("FieldCount") += 1
placeTextBoxes.Controls.Clear()
DrawAllRows()
End Sub
Protected Sub cmdSubtractRow_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles cmdSubtractRow.Click

ViewState("FieldCount") -= 1
placeTextBoxes.Controls.Clear()
DrawAllRows()
End Sub
Protected Sub cmdPostback_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles cmdPostback.Click

lblControlList.Text = ListAllControls(Page)
End Sub
Private Sub DrawAllRows()

Dim intCounter As Integer
Dim intMaxCount As Integer
intMaxCount = CInt(ViewState("FieldCount"))
If intMaxCount 1 Then
For intCounter = 2 To intMaxCount
AddRowOfControls(intCounter)
Next
End If
lblControlList.Text = ListAllControls(Page)
End Sub
Private Sub AddRowOfControls(ByVal intRowCount As Integer)

Dim litLabel As LiteralControl
Dim txtTextBox As TextBox
Dim cmdAddRow As Button
Dim cmdSubtractRow As Button
litLabel = New LiteralControl
litLabel.Text = "<br>"
placeTextBoxes.Controls.Add(litLabel)
txtTextBox = New TextBox
txtTextBox.Text = "txtProduct " & intRowCount.ToString
placeTextBoxes.Controls.Add(txtTextBox)
cmdAddRow = New Button
cmdAddRow.Text = "+"
AddHandler cmdAddRow.Click, AddressOf cmdAddRow_Click
placeTextBoxes.Controls.Add(cmdAddRow)
cmdSubtractRow = New Button
cmdSubtractRow.Text = "-"
AddHandler cmdSubtractRow.Click, AddressOf cmdSubtractRow_Click
placeTextBoxes.Controls.Add(cmdSubtractRow)
End Sub
Private Function ListAllControls(ByVal objContainter As Control) As
String

Dim strBuilder As New StringBuilder
Dim ctlText As TextBox
For Each ctl As Control In objContainter.Controls
If ctl.Controls.Count 0 Then
strBuilder.Append(ListAllControls(ctl))
Else
If TypeOf ctl Is TextBox Then
ctlText = CType(ctl, TextBox)
strBuilder.Append("<br>")
strBuilder.Append(ctlText.Text)
End If
End If
Next
If Not ctlText Is Nothing Then
ctlText.Dispose()
End If
Return strBuilder.ToString
End Function
__________________________________________________ ________
What could be simpler ? And still.... If I click only the + and the -
buttons which have NOT been created dynamically, everything is just
fine. However, if I click on the newly created buttons, let's say on
the + button, I need TWO clicks - one changes the text in the last
textbox from, say, "txtProduct 5" to "txtProduct 2", and the second
click finally adds a new row and now everything is correct - it adds
"txtProduct 6" and I obtain the list of controls as follows:

txtProduct 1
txtProduct 2
txtProduct 3
txtProduct 4
txtProduct 5
txtProduct 6
What's wrong with this approach ? I'm obviously missing something ! ;-
((

Thank you very much.
Alex

Jun 8 '07 #2

P: n/a
On Jun 8, 12:14 pm, Yuriy Solodkyy <e...@nospam.nospamwrote:
Hi

That is because ommand buttons clicks are invoked by control ID. When you
recreate controls while handling click event, you create new controls with
new IDs. However, next time on postback the same controls are created with
different IDs. Therefore, if page was generated with recreating controls
command buttons IDs are different.

Try assigning unique IDs to your controls and try not recreating already
existing controls. I.e if you add new line of controls just add it without
clearing existing.

To see your problem replace

strBuilder.Append(ctlText.Text)

with
strBuilder.Append(ctlText.Text + " " + ctlText.UniqueID)

And see how IDs chnage.

yuriy
Hi. I have a page with the following html:
__________________________________________________ ________
<h1>Dynamic Controls Test</h1>
<hr />
<asp:TextBox ID="txtProduct1" Text="txtProduct 1" runat="server"></
asp:TextBox>
<asp:Button ID="cmdAddRow" Text="+" AccessKey="+" runat="server" />
<asp:Button ID="cmdSubtractRow" Text="-" AccessKey="+" runat="server"
/
<asp:PlaceHolder runat="server" id="placeTextBoxes" />
<hr />
<asp:Button ID="cmdPostback" Text="Postback !" runat="server" />
<br />
<asp:label runat="server" id="lblControlList" />
__________________________________________________ ________
and the code
__________________________________________________ ________ Protected
Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles Me.Load
If Not IsPostBack Then
'Initial load...
ViewState("FieldCount") = 1
End If
DrawAllRows()
End Sub
Protected Sub cmdAddRow_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles cmdAddRow.Click
ViewState("FieldCount") += 1
placeTextBoxes.Controls.Clear()
DrawAllRows()
End Sub
Protected Sub cmdSubtractRow_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles cmdSubtractRow.Click
ViewState("FieldCount") -= 1
placeTextBoxes.Controls.Clear()
DrawAllRows()
End Sub
Protected Sub cmdPostback_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles cmdPostback.Click
lblControlList.Text = ListAllControls(Page)
End Sub
Private Sub DrawAllRows()
Dim intCounter As Integer
Dim intMaxCount As Integer
intMaxCount = CInt(ViewState("FieldCount"))
If intMaxCount 1 Then
For intCounter = 2 To intMaxCount
AddRowOfControls(intCounter)
Next
End If
lblControlList.Text = ListAllControls(Page)
End Sub
Private Sub AddRowOfControls(ByVal intRowCount As Integer)
Dim litLabel As LiteralControl
Dim txtTextBox As TextBox
Dim cmdAddRow As Button
Dim cmdSubtractRow As Button
litLabel = New LiteralControl
litLabel.Text = "<br>"
placeTextBoxes.Controls.Add(litLabel)
txtTextBox = New TextBox
txtTextBox.Text = "txtProduct " & intRowCount.ToString
placeTextBoxes.Controls.Add(txtTextBox)
cmdAddRow = New Button
cmdAddRow.Text = "+"
AddHandler cmdAddRow.Click, AddressOf cmdAddRow_Click
placeTextBoxes.Controls.Add(cmdAddRow)
cmdSubtractRow = New Button
cmdSubtractRow.Text = "-"
AddHandler cmdSubtractRow.Click, AddressOf cmdSubtractRow_Click
placeTextBoxes.Controls.Add(cmdSubtractRow)
End Sub
Private Function ListAllControls(ByVal objContainter As Control) As
String
Dim strBuilder As New StringBuilder
Dim ctlText As TextBox
For Each ctl As Control In objContainter.Controls
If ctl.Controls.Count 0 Then
strBuilder.Append(ListAllControls(ctl))
Else
If TypeOf ctl Is TextBox Then
ctlText = CType(ctl, TextBox)
strBuilder.Append("<br>")
strBuilder.Append(ctlText.Text)
End If
End If
Next
If Not ctlText Is Nothing Then
ctlText.Dispose()
End If
Return strBuilder.ToString
End Function
__________________________________________________ ________
What could be simpler ? And still.... If I click only the + and the -
buttons which have NOT been created dynamically, everything is just
fine. However, if I click on the newly created buttons, let's say on
the + button, I need TWO clicks - one changes the text in the last
textbox from, say, "txtProduct 5" to "txtProduct 2", and the second
click finally adds a new row and now everything is correct - it adds
"txtProduct 6" and I obtain the list of controls as follows:
txtProduct 1
txtProduct 2
txtProduct 3
txtProduct 4
txtProduct 5
txtProduct 6
What's wrong with this approach ? I'm obviously missing something ! ;-
((
Thank you very much.
Alex- Hide quoted text -

- Show quoted text -

Thank you, thank you, thank you !!!
That was it - it works like a charm now.
Did I say Thank you ? :-)))
Alex

Jun 8 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.