why the form posted values are not those submitted by users? - asp.net

I use Asp.net web forms. I have a form with a table and a combo box. The table changes as the selected item of the combo box changes. The combo box is an asp.net control and I set autopostback = true. The table is also an asp.net control, and all table cells are created/rendered in the server side.
Users will input values in the table and submit it to the server.
The problem I find is that when a user changes the selected item of the combo box, the table changes and the web page rendered correctly. Then the user inputs some values and clicks submit. From the server side, the value I get is the default values of the table, not the user inputs. If the user submits again, the server side can get the user inputs.
Here is the code I write to reproduce this issue. I create a default web form project, add a new web from which inherits the site master. To reproduce, take following steps: 1. select one radio button 2. submit and you will see a text about your selection at the top of the page. 3. change the combo box selection 4. select another radio button 5. submit and you will find the bug. 6. redo 4 and 5, you will find the text correct.
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="PostBackUsingMasterPage.aspx.cs" Inherits="WebFormBug.PostBackUsingMasterPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="FeaturedContent" runat="server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
<asp:DropDownList ID="comboBox" runat="server" AutoPostBack="true" OnSelectedIndexChanged="UpdateTable">
<asp:ListItem>Apple</asp:ListItem>
<asp:ListItem>Beet</asp:ListItem>
<asp:ListItem>Citron</asp:ListItem>
</asp:DropDownList>
<asp:Label ID="userInput" runat="server"></asp:Label>
<asp:Table runat="server" ID="testTable"> </asp:table>
<asp:Button ID="submit" runat="server" Text="Submit for validation" OnClick="SubmitButton_Click" />
</asp:Content>
The aspx.cs is like this
using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
namespace WebFormBug
{
public partial class PostBackUsingMasterPage : Page
{
private string _scope;
protected void Page_Load(object sender, EventArgs e)
{
_scope = comboBox.SelectedValue ?? "Apple";
PopUpTable(_scope);
}
private void PopUpTable(string item)
{
testTable.Rows.Clear();
var row = new TableRow();
row.Cells.Add(new TableCell {Text = item});
row.Cells.Add(AddRadioButtons(item));
testTable.Rows.Add(row);
}
private TableCell AddRadioButtons(string name)
{
var cell = new TableCell();
var radioButtons = new HtmlInputRadioButton[5];
for (var i = 0; i < 3; i++)
{
radioButtons[i] = new HtmlInputRadioButton { Name = name, Value = name + " " + i };
cell.Controls.Add(radioButtons[i]);
var label = new Label { Text = name + " " + i };
cell.Controls.Add(label);
}
return cell;
}
protected void UpdateTable(object sender, EventArgs e)
{
PopUpTable(comboBox.SelectedValue);
}
protected void SubmitButton_Click(object sender, EventArgs e)
{
int valueIndex = 1;
for (int i = 0; i < testTable.Rows.Count; i++)
{
var row = testTable.Rows[i];
string inputValue = null, inputName = null;
foreach (var ctrl in row.Cells[valueIndex].Controls)
{
if (ctrl is HtmlInputRadioButton)
{
var radioInput = (HtmlInputRadioButton) ctrl;
if (!radioInput.Checked) continue;
inputValue = radioInput.Value;
inputName = radioInput.Name;
break;
}
}
if (inputName != null && inputValue != null)
{
userInput.Text = inputName + " " + inputValue;
}
}
}
}
}

Preparation knowledge of ASP.NET WebForm: dynamically added table data is missing from form post asp.net table adding rows dynamically don't remain after postback. Your sample is the case - you are composing table data dynamically.
Solution for posting back dynamic table data is to re-create the form data in each post back in (and should ONLY in) page Load method. and your sample is doing this (the PopUpTable method is always called in Page_Load).
However, in your code Page_Load is not the only place doing table re-creation, but also in OnSelectedIndexChanged which results in cleaning your table data. Actually, you don't need register this event.
So, solution (sorry for attaching the code as image, but I found attaching large segment of code is very hard to format):
Remove OnSelectedIndexChanged
Change code behind as below:

Try this:
in page load:
if(!IsPostBack)
{
// set data to table
}

I'm assuming you have updatepanel with which the change of the selected index on the dropdown updates the radiobuttons. You could try changing the eventhandler for the dropdown to
protected void UpdateTable(object sender, EventArgs e)
{
if (!IsPostBack)
{
PopUpTable(comboBox.SelectedValue);
}
}

Related

Why binding event is not called after submit button clicked for user control (added code)

I have a web page that uses single user control and a asp:repeater that uses the same user control and both are created in Page_Load. Both bahave differently in a submit button clicking event. The binding event for each of the repeater (depdentBasicInfo)'s user control is called after submit button clicking before page_load. But the binding event is not for the single user control (spouseBasicInfo). Why? Also the user control create a runtime control (assuming a TextBox). I found there is no way to retrieve the runtime control's Text property after clicking the submit as the control becomes null after PostBack. How to retrieve the property easily? Could any one help me? Thanks.
<!--USER CONTROL -->
<asp:Panel runat="server" ID="PnlSpouseInformation" Visible="true">
<h3 id="ApplicantLabel" runat="server"></h3>
<div class="dependentInformation">
<asp:PlaceHolder ID="phDependentInformation" runat="server"></asp:PlaceHolder>
</div>
</asp:Panel>
<!-- code behind -->
public partial class userInfo : System.Web.UI.UserControl
{
public string identity;
public string applicantTitle
{
set { ApplicantLabel.InnerText = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
}
public void Bind()
{
WebControl textBox = new TextBox
{
Text = identity,
ID = "textbox"
};
phDependentInformation.Controls.Add(textBox);
}
}
<html>
<head runat="server">
<title>Test user control binding</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<uc1:userInfo runat="server" ID="SpouseBasicInfo" Visible="false" />
<asp:Repeater runat="server" ID="RptDependents" OnItemCreated="RptDependents_ItemCreated">
<ItemTemplate>
<uc1:userInfo runat="server" ID="DependentBasicInfo" />
</ItemTemplate>
</asp:Repeater>
<asp:LinkButton runat="server" ID="submit" OnClick="OnClickSubmit"><span>Submit</span></asp:LinkButton>
</div>
</form>
</body>
public partial class _default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SpouseBasicInfo.identity = "spouse";
SpouseBasicInfo.Bind();
SpouseBasicInfo.Visible = true;
List<String> list = new List<string>();
list.Add("Dependent A");
list.Add("Dependent B");
RptDependents.DataSource = list;
RptDependents.DataBind();
}
}
protected void OnClickSubmit(object sender, EventArgs e)
{
if (!Page.IsValid)
{
return;
}
var textbox = SpouseBasicInfo.FindControl("textbox") as TextBox;
string spouseName = textbox.Text;
}
protected void RptDependents_ItemCreated(object sender, RepeaterItemEventArgs e)
{
switch (e.Item.ItemType)
{
case ListItemType.Item:
case ListItemType.AlternatingItem:
{
var dependentInfo = e.Item.DataItem as String;
var dependentBasicInfo = e.Item.FindControl("DependentBasicInfo") as userInfo;
if (dependentBasicInfo == null) return;
dependentBasicInfo.applicantTitle = "Dependent " + (e.Item.ItemIndex + 1);
dependentBasicInfo.identity = dependentInfo;
dependentBasicInfo.Bind();
}
break;
}
}
}
</html>
Can you please post your code so we can get a look at it? Also, you say the runtime control becomes null after post back. Is the text property of the control set after the page is rendered? if so you may be able to use a hidden asp label on the page that can hold the text property. When the page is posted back the hidden label still holds the last value held for the text property of said control.
"User control (spouseBasicInfo). Why? Also the user control create a runtime control (assuming a TextBox). I found there is no way to retrieve the runtime control's Text property after clicking the submit as the control becomes null after PostBack. How to retrieve the property easily? Could any one help me? Thanks."
I haven't been working with asp.net for a long time so I don't think I can answer all the questions you are asking. But, if you are creating a text box at runtime and using the placeholder to deliver the object to the screen then yes, the textbox control will be null after post back. This is because it is not an asp.control like a textbox or label that is not runtime created. You can retrieve the value previously held in the text box by creating a label on screen that is hidden. Place your value in the hidden label and the runtime created text box. After post back the hidden label will still hold the value previous to post back and you can retrieve as you would normally retrieve a value held in a control. I hope this helps you get a step closer to solving your issue. Sorry I can't be of more help. Good luck.

How to find nested controls within nested user controls

I have a user control (Control1) which has a placeholder that may contain several additional user controls (of the same type - see below) which are added dynamically. How do I navigate the user control hierarchy to find the values of the nested sets of controls when the button located in Control 1 is clicked?
Control 1:
<%# Control Language="C#" AutoEventWireup="True" CodeBehind="Control1.ascx.cs" Inherits="Control1" %>
<%# Reference Control="Control2.ascx" %>
<div id="div1">
<div id="divPh"><asp:PlaceHolder ID="phControls" runat="server" /></div>
<div id="divContinue"><asp:Button ID="btnContinue" Text="Continue" OnClick="submit_Click" runat="server" /></div>
</div>
Code behind for Control1.aspx:
protected void submit_Click(object sender, EventArgs e)
{
// iterate through list of divControl2 controls and find out which radio button is selected
// for example, there may be 3 divControl2's which are added to the placeHolder on Control1, rdoBth1 might be selected on 2 of the controls
// and rdoBtn2 might be selected on 1 - how do I navigate this control structure?
}
Control 2 (Several of these may be added to the placeHolder on Control1):
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="Control2.ascx.cs" Inherits="Control2" %>
<div id="divControl2">
<p><strong><asp:RadioButton ID="rdoBtn1" GroupName="Group1" Checked="true" runat="server" /> Check this</strong></p>
<p><strong><asp:RadioButton ID="rdoBtn2" GroupName="Group1" Checked="false" runat="server" /> No, check this one</strong></p>
</div>
Check below code and let me know if you have any queries.
protected void submit_Click(object sender, EventArgs e)
{
for (int count = 0; count < phControls.Controls.Count; count++)
{
UserControl uc = (UserControl)(phControls.Controls[count]);
if (uc != null)
{
RadioButton rdoBtn1 = new RadioButton();
RadioButton rdoBtn2 = new RadioButton();
rdoBtn1 = (RadioButton)(uc.FindControl("rdoBtn1"));
rdoBtn2 = (RadioButton)(uc.FindControl("rdoBtn2"));
if (rdoBtn1.Checked == true)
{
Response.Write("1st checked ");
}
else if (rdoBtn2.Checked == true)
{
Response.Write("2nd checked");
}
}
}
This isn't the best design in the world, but you can accomplish what you're looking for with some relative ease. The problem is that the page where these controls are will have to have intimate knowledge of the inner workings of the dynamically added controls. And, you're going to want them to implement a common abstract class or interface so that you can look for the right ones by type.
The following code assumes that you've created properties for accessing the internal controls values rather than having to reference the internal controls yourself. This is just good practice when you use any kind of control.
protected void submit_Click(object sender, EventArgs e) {
foreach (var control in phControls.Controls) {
IMySpecialControl mySpecialControl = control as IMySpecialControl;
if (mySpecialControl != null) {
// access some properties (and probably need a cast to the specific control type :(
}
}
}
Instead, why not just access the fields via Request.Form collection instead?
string rdoBtn1Value = Request.Form["rdoBtn1"];

How to programmatically create and use a list of checkboxes from ASP.NET?

I have a page with a table of stuff and I need to allow the user to select rows to process. I've figured out how to add a column of check boxes to the table but I can't seem to figure out how to test if they are checked when the form is submitted. If they were static elements, I'd be able to just check do this.theCheckBox but they are programaticly generated.
Also I'm not very happy with how I'm attaching my data to them (by stuffing it in there ID property).
I'm not sure if it's relevant but I'm looking at a bit of a catch-22 as I need to known which of the checkboxes that were created last time around were checked before I can re-run the code that created them.
Edit:
I've found an almost solution. By setting the AutoPostBack property and the CheckedChanged event:
checkbox.AutoPostBack = false;
checkbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
I can get code to be called on a post back for any check box that has changed. However this has two problems:
The call back is processed after (or during, I'm not sure) Page_Load where I need to use this information
The call back is not called for check boxes that were checked when the page loaded and still are.
Edit 2:
What I ended up doing was tagging all my ID's with a know prefix and stuffing this at the top of Form_Load:
foreach (string v in this.Request.Form.AllKeys)
{
if (v.StartsWith(Prefix))
{
var data = v.Substring(Prefix.Length);
}
}
everything else seems to run to late.
I'm going to assume you're using a DataList but this should work with and Control that can be templated. I'm also going to assume you're using DataBinding.
Code Front:
<asp:DataList ID="List" OnItemDataBound="List_ItemDataBound" runat="server">
<ItemTemplate>
<asp:CheckBox ID="DeleteMe" runat="server"/>
<a href="<%# DataBinder.Eval(Container, "DataItem.Url")%>" target="_blank">
<%# DataBinder.Eval(Container, "DataItem.Title")%></a>
</ItemTemplate>
</asp:DataList>
<asp:Button ID="DeleteListItem" runat="server" OnClick="DeleteListItem_Click" ></asp:Button>
Code Behind:
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadList();
}
protected void DeleteListItem_Click(object sender, EventArgs e)
{
foreach (DataListItem li in List.Items)
{
CheckBox delMe = (CheckBox)li.FindControl("DeleteMe");
if (delMe != null && delMe.Checked)
//Do Something
}
}
LoadList();
}
protected void LoadList()
{
DataTable dt = //Something...
List.DataSource = dt;
List.DataBind();
}
protected void List_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
string id = DataBinder.Eval(e.Item.DataItem, "ID").ToString();
CheckBox delMe = (CheckBox)e.Item.FindControl("DeleteMe");
if (delMe != null)
delMe.Attributes.Add("value", id);
}
}
}
First, make sure that each Checkbox has an ID and that it's got the 'runat="server"' in the tag.
then use the FindControl() function to find it.
For example, if you're looping through all rows in a GridView..
foreach(GridViewRow r in Gridview1.Rows)
{
object cb = r.FindControl("MyCheckBoxId");
if(r != null)
{
CheckBox chk = (CheckBox)cb;
bool IsChecked = chk.Checked;
}
}
Postback data is restored between the InitComplete event and the PreLoad event. If your checkboxes are not created until later then the checkboxes will play "catch up" with their events and the data will be loaded into the control shortly after it is created.
If this is to late for you then you will have to do something like what you are already doing. That is you will have to access the post data before it is given to the control.
If you can save the UniqueId of each CheckBox that you create then can directly access the post data without having to given them a special prefix. You could do this by creating a list of strings which you save the ids in as you generate them and then saving them in the view state. Of course that requires the view state to be enabled and takes up more space in the viewstate.
foreach (string uniqueId in UniqueIds)
{
bool data = Convert.ToBoolean(Request.Form[uniqueId]);
//...
}
Your post is a little vague. It would help to see how you're adding controls to the table. Is it an ASP:Table or a regular HTML table (presumably with a runat="server" attribute since you've successfully added items to it)?
If you intend to let the user make a bunch of selections, then hit a "Submit" button, whereupon you'll process each row based on which row is checked, then you should not be handling the CheckChanged event. Otherwise, as you've noticed, you'll be causing a postback each time and it won't process any of the other checkboxes. So when you create the CheckBox do not set the eventhandler so it doesn't cause a postback.
In your submit button's eventhandler you would loop through each table row, cell, then determine whether the cell's children control contained a checkbox.
I would suggest not using a table. From what you're describing perhaps a GridView or DataList is a better option.
EDIT: here's a simple example to demonstrate. You should be able to get this working in a new project to test out.
Markup
<form id="form1" runat="server">
<div>
<table id="tbl" runat="server"></table>
<asp:Button ID="btnSubmit" runat="server" Text="Submit"
onclick="btnSubmit_Click" />
</div>
</form>
Code-behind
protected void Page_Load(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
var row = new HtmlTableRow();
var cell = new HtmlTableCell();
cell.InnerText = "Row: " + i.ToString();
row.Cells.Add(cell);
cell = new HtmlTableCell();
CheckBox chk = new CheckBox() { ID = "chk" + i.ToString() };
cell.Controls.Add(chk);
row.Cells.Add(cell);
tbl.Rows.Add(row);
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
foreach (HtmlTableRow row in tbl.Rows)
{
foreach (HtmlTableCell cell in row.Cells)
{
foreach (Control c in cell.Controls)
{
if (c is CheckBox)
{
// do your processing here
CheckBox chk = c as CheckBox;
if (chk.Checked)
{
Response.Write(chk.ID + " was checked <br />");
}
}
}
}
}
}
What about using the CheckBoxList control? I have no Visual Studio open now, but as far as I remember it is a DataBound control, providing DataSource and DataBind() where you can provide a list at runtime. When the page does a postback you can traverse the list by calling something like myCheckBoxList.Items and check whether the current item is selected by calling ListItem.Selected method. This should work.
Add them in an override of the CreateChildControls method of the Page. Be sure to give them an ID! This way they get added to the control tree at the correct time.
IMHO The best way would be to use DataBound Templated Control though, i.e. something like a ListView (in .NET 3.5). then in pageload after postback traverse all items in the databound control and use item.FindControl to get at the actual checkbox.
What I ended up doing was tagging all my ID's with a know prefix and stuffing this at the top of Form_Load:
foreach (string v in this.Request.Form.AllKeys)
{
if (v.StartsWith(Prefix))
{
var data = v.Substring(Prefix.Length);
}
}
everything else seems to run to late.

ASP.NET + jQuery + Dynamically Created HyperLink controls

I have an ASP.NET application that uses jQuery. My ASP.NET application dynamically generates some HyperLink elements based on some values in a database. When a user clicks one of these HyperLink elements, I want to display a jQuery dialog box that allows the user to edit the text of the HyperLink. I have this part working.
When a user clicks the "Save" button, I need to read the values of the HyperLink elements and save them back to the database. Currently, I get the initial values of the HyperLink elements. However, I cannot get any modified values. How do I get the values that were provided by the user? I have provided my .aspx and .aspx.cs code here:
test
Report:
<div id="recommendDialog" title="Number">
<table border="0" cellpadding="0" cellspacing="0">
<tr><td>Number</td></tr>
<tr><td><input id="optionName" type="text" /></td></tr>
</table>
</div>
<asp:Button ID="saveButton" runat="server" Text="Save" OnClick="saveButton_Click" />
</div>
</form>
<script type="text/javascript">
var editingID = null;
$("#recommendDialog").dialog({
autoOpen: false,
height: 200,
modal: true,
buttons: {
Cancel: function() {
$(this).dialog('close');
},
'OK': function() {
var newValue = $("#optionName").val();
if (editingID != null) {
$(editingID).attr("name", newValue);
$(editingID).html(newValue);
}
$(this).dialog('close');
}
},
close: function() {
}
});
function update_Click(link) {
editingID = "#" + link.id;
$("#optionName").val(link.name);
$('#recommendDialog').dialog('open');
}
</script>
Here is my code-behind:
public partial class _Default : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
AddHyperlinks();
}
protected void Page_Load(object sender, EventArgs e)
{}
protected void saveButton_Click(object sender, EventArgs e)
{
foreach (TableCell cell in reportTable.Rows[0].Cells)
{
HyperLink h = (HyperLink)(cell.Controls[0]);
string newValue = h.Attributes["name"];
// Save value to database here. newValue does not show
// changed values.
Console.WriteLine(newValue);
}
}
private void AddHyperlinks()
{
TableRow row = new TableRow();
for (int i = 1; i < 11; i++)
{
HyperLink hyperlink = new HyperLink();
hyperlink.NavigateUrl = "#";
hyperlink.Text = i.ToString();
hyperlink.Attributes.Add("id", "h" + i);
hyperlink.Attributes.Add("name", i.ToString());
hyperlink.Attributes.Add("onclick", "update_Click(this);");
AddLinkButtonToRow(hyperlink, row);
}
reportTable.Rows.Add(row);
}
private void AddLinkButtonToRow(HyperLink linkButton, TableRow row)
{
TableCell cell = new TableCell();
cell.Controls.Add(linkButton);
row.Cells.Add(cell);
}
}
What you're trying to do isn't possible that way. You create links every time the page is created. Although you change the name of these links in JavaScript, these values are not posted back to you.
On Sumbit, only form elements get posted back to the server (<input>s, for example), not <a> elements, so your server doesn't "know" the changes were made.
Secondly, even if you'll change the <a>s to <input>s, you still have a problem: you won't be able to find these values in reportTable.Rows[0].Cells as you expect. Normally asp.net will fill these values correctly, even for dynamically generated controls, but not here - since you've changed their names! Asp.net cannot rebind these values.
So, what should you do? One option is to add an hidden field to every cell.
On AddLinkButtonToRow, add the following:
HtmlInputHidden hidden = new HtmlInputHidden();
hidden.ID = "hidden" + linkButton.ID;
hidden.Name = hidden.ID; //so it will be posted!
hidden.Style["display"] = "none"; //better to have a CssClass
Using jQuery, which you seem to know, change the values of these input fields, not their names (something like $(editingID).parent().find(":hidden")).
Next, you might not see the values on the controls, but you can find them at Request.Form["hiddenh1"] ... Request.Form["hiddenh11"] - All input fields will names will be posted, and you know their names this time.
I'm not sure where or what "ReportTable" and it's tablecells are, but I'm guessing your problem is that you're manipulating the value of some tags on the client using jQuery, and expecting them to be posted back to the server?
This won't work. The page got rendered with known values of your HyperLink controls in ViewState. Since tags are not input types, they will not post a value back to the server on a postback, and ViewState will always re-initialize them with their original values. Any manipulation must be done on the server side.
I would recommend doing what ScottE suggests and do your update with jquery ajax.

Adding controls dynamically to an UpdatePanel in ASP.NET AJAX

I have the following really simple code
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:PlaceHolder ID="PlaceHolder1" runat="server">
</asp:PlaceHolder>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>
And the codebehind
protected void Button1_Click(object sender, EventArgs e)
{
Literal literal = new Literal();
literal.Text = DateTime.Now.ToString();
literal.ID = DateTime.Now.Ticks.ToString();
// These both work fine the first time the button is clicked
// but the second time nothing is added.
UpdatePanel1.ContentTemplateContainer.Controls.Add(literal);
PlaceHolder1.Controls.Add(literal);
}
My problem comes in that the Literal control is only ever added once. I've scoured google and blog sites (plus books) but without any luck. What am I missing?
In asp.net, the controls in the ASPX file are automatically generated on each postback. The controls you've created are not in the ASPX code so the framework does not create them for you. The first time you execute the Button1_Click method, you add one extra control to the page. The second time you execute the Button1_Click method, you're on another post back and that first extra button has been forgotten about. So the result of that postback is you get one extra button again.
This will create one extra control each time you click the button (although the timestamps will update each time you press the button because the controls are being re-created)
protected void Button1_Click(object sender, EventArgs e)
{
int count = 0;
if (ViewState["ButtonCount"] != null)
{
count = (int)ViewState["ButtonCount"];
}
count++;
ViewState["ButtonCount"] = count;
for (int i = 0; i < count; i++)
{
Literal literal = new Literal();
literal.Text = DateTime.Now.ToString();
literal.ID = DateTime.Now.Ticks.ToString();
UpdatePanel1.ContentTemplateContainer.Controls.Add(literal);
PlaceHolder1.Controls.Add(literal);
}
}
I agree to the answer above, However this approach will not save the state of the dynamic controls (or to be accurate, it will save the state but not load them back).
Load view state is called in Load event section of page life cycle,where it assigns back the control values saved in view state.
However if the controls are not created by this time, They can not be loaded with previous data so for the state to be maintained, the new controls must be recreated on or before load event.
protected void Page_Load(object sender, EventArgs e)
{
//PS: Below approach saves state as id is constant, it simply generates a new control with same id hence viewstate loads the value
if (IsPostBack)
{
int count = 0;
if (ViewState["ButtonCount"] != null)
{
count = (int)ViewState["ButtonCount"];
}
count++;
ViewState["ButtonCount"] = count;
for (int i = 0; i < count; i++)
{
TextBox literal = new TextBox();
//literal.Text = DateTime.Now.ToString();
literal.ID = "Textbox" + i.ToString();
//UpdatePanel1.ContentTemplateContainer.Controls.Add(literal);
PlaceHolder1.Controls.Add(literal);
}
}
}
Dynamically adding controls
View State and postback

Resources