Dynamic Controls - How to access postback data?

  • Thread starter Thread starter DylanSmith
  • Start date Start date
D

DylanSmith

I have a WebForm where I'm dynamically creating some controls and I'm having
difficulty understanding how the state is being persisted and how to work
with it.

I've created a simplified example to demonstrate my issues. Lets say I have
a WebForm with a DropDownList where the user selects a number from 1 to 10
(the DropDownList is not dynamically created). I also have a button on there
that I use to trigger a PostBack.

Based on the user's selection in the drop-down I want to create that many
textboxes programatically. I got this part working easily enough by putting
some code in the Page_Load event. The new textboxes even maintain their
values correctly across post-backs.

But what if I want to put a LiteralControl on my page that will display the
sum of the values entered in all the dynamic textboxes. The problem is where
do I put this code so that it can access the data in the dynamic textboxes
after their values have been restored from the postback data?

Based on my understanding of the page lifecycle (from this article:
http://msdn.microsoft.com/en-us/library/ms972976.aspx) I was assuming that
when I added the TextBoxes to the Panel it was triggering some processing
behind the scenes that caused the "LoadPostbackData" logic to be applied to
the textboxes. This would explain how the textbox values were being
maintained across postbacks. If this were true I should be able to put my
adding code immediately after adding the textboxes to the panels and their
properties should be set to the appropriate values.

This turns out not to work, and the Sum always displays as 0.

If you're going to suggest I use the Init event to create the dynamic
textboxes then I have the problem of retrieving the value from the
DropDownList that tells me how many I need to create, because the
DropDownList's SelectedItem hasn't been updated yet in the Init event because
the PostBack data hasn't been applied (that's why I was using the Load event).

Here is the code I have:

AddingMachine.aspx
==================
<body>
<form id="form1" runat="server">
<div>

<asp:DropDownList ID="DropDownList1" runat="server">
<asp:ListItem>1</asp:ListItem>
<asp:ListItem>2</asp:ListItem>
<asp:ListItem>3</asp:ListItem>
<asp:ListItem>4</asp:ListItem>
<asp:ListItem>5</asp:ListItem>
<asp:ListItem>6</asp:ListItem>
<asp:ListItem>7</asp:ListItem>
<asp:ListItem>8</asp:ListItem>
<asp:ListItem>9</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="Button1" runat="server" Text="Button" />
<asp:Literal ID="Literal1" runat="server"></asp:Literal>

<asp:Panel ID="Panel1" runat="server"></asp:Panel>
</div>
</form>
</body>


AddingMachine.aspx.cs
=====================
public partial class AddingMachine : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
for (int i = 0; i < Int32.Parse(DropDownList1.SelectedItem.Value);
i++) {
TextBox NewTextBox = new TextBox();
NewTextBox.Text = "0";
Panel1.Controls.Add(NewTextBox);
}

int Sum = 0;

foreach(Control CurControl in Panel1.Controls) {
if(CurControl.GetType() == typeof(TextBox)) {
TextBox TargetTextBox = (TextBox)CurControl;
Sum += Int32.Parse(TargetTextBox.Text);
}
}
Literal1.Text = "Sum = " + Sum.ToString();
}
}
 
DylanSmith presented the following explanation :
I have a WebForm where I'm dynamically creating some controls and I'm having
difficulty understanding how the state is being persisted and how to work
with it.

I've created a simplified example to demonstrate my issues. Lets say I have
a WebForm with a DropDownList where the user selects a number from 1 to 10
(the DropDownList is not dynamically created). I also have a button on there
that I use to trigger a PostBack.

Based on the user's selection in the drop-down I want to create that many
textboxes programatically. I got this part working easily enough by putting
some code in the Page_Load event. The new textboxes even maintain their
values correctly across post-backs.

But what if I want to put a LiteralControl on my page that will display the
sum of the values entered in all the dynamic textboxes. The problem is where
do I put this code so that it can access the data in the dynamic textboxes
after their values have been restored from the postback data?

Based on my understanding of the page lifecycle (from this article:
http://msdn.microsoft.com/en-us/library/ms972976.aspx) I was assuming that
when I added the TextBoxes to the Panel it was triggering some processing
behind the scenes that caused the "LoadPostbackData" logic to be applied to
the textboxes. This would explain how the textbox values were being
maintained across postbacks. If this were true I should be able to put my
adding code immediately after adding the textboxes to the panels and their
properties should be set to the appropriate values.

This turns out not to work, and the Sum always displays as 0.

If you're going to suggest I use the Init event to create the dynamic
textboxes then I have the problem of retrieving the value from the
DropDownList that tells me how many I need to create, because the
DropDownList's SelectedItem hasn't been updated yet in the Init event because
the PostBack data hasn't been applied (that's why I was using the Load
event).

Here is the code I have:

AddingMachine.aspx
==================
<body>
<form id="form1" runat="server">
<div>

<asp:DropDownList ID="DropDownList1" runat="server">
<asp:ListItem>1</asp:ListItem>
<asp:ListItem>2</asp:ListItem>
<asp:ListItem>3</asp:ListItem>
<asp:ListItem>4</asp:ListItem>
<asp:ListItem>5</asp:ListItem>
<asp:ListItem>6</asp:ListItem>
<asp:ListItem>7</asp:ListItem>
<asp:ListItem>8</asp:ListItem>
<asp:ListItem>9</asp:ListItem>
</asp:DropDownList>
<asp:Button ID="Button1" runat="server" Text="Button" />
<asp:Literal ID="Literal1" runat="server"></asp:Literal>

<asp:Panel ID="Panel1" runat="server"></asp:Panel>
</div>
</form>
</body>


AddingMachine.aspx.cs
=====================
public partial class AddingMachine : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
for (int i = 0; i < Int32.Parse(DropDownList1.SelectedItem.Value);
i++) {
TextBox NewTextBox = new TextBox();
NewTextBox.Text = "0";
Panel1.Controls.Add(NewTextBox);
}

int Sum = 0;

foreach(Control CurControl in Panel1.Controls) {
if(CurControl.GetType() == typeof(TextBox)) {
TextBox TargetTextBox = (TextBox)CurControl;
Sum += Int32.Parse(TargetTextBox.Text);
}
}
Literal1.Text = "Sum = " + Sum.ToString();
}
}

Try moving the sum-code to the PreRender event.
I think that "LoadPostbackData" is executed immediately *after* the
"Load", so too late for your code but in time for the PreRender.

Hans Kesting
 
Hans Kesting said:
Try moving the sum-code to the PreRender event.
I think that "LoadPostbackData" is executed immediately *after* the
"Load", so too late for your code but in time for the PreRender.

Hans Kesting


Thanks Hans, that works great and should solve both my simplifiied scenario
and my actual real-world scenario.

But just for curiosities sake, what if I had a more involved scenario where
I needed to read the value of my drop-down and use that to create some
dynamic controls, then read the values in my dynamic controls and use that to
create some more and then read the values of those and perform some logic,
and so on and so on.

Is there a way to explicitly force the "LoadPostbackData" processing to
occur without having to wait for the PreRender event?
 
Hello kumar,
Can u send me the code.because i am also having the same problem pls
send me

Kumar this seems to ba a bit vague. I cannot tell who you are replying to.

Perhaps choose to "Reply" to the original post instead of creating a "new
post" ?
 
Back
Top