I have seen two few other posts related to this but I have doubts related to my code. So kindly bear with me.
I have user control which has a text boa and a drop down list and few custom validators.
The user control is added dynamically through a code.
I am using follwoing code to load the dropdownlist inside user control itself
protected void Page_Load(object sender, EventArgs e)
{
ddl_RRC.DataSource = dicRC_Desc;
ddl_RRC.DataTextField = "value";
ddl_RRC.DataValueField = "key";
ddl_RRC.DataBind();
txtRC.Text = Request.Form[txtRC.UniqueID]; //To retain the value of text box
}
I am adding the user control dynamically on Page_Init
protected void Page_Init(object sender, EventArgs e)
{
if (GetPostBackControl(this) == "btnNewRow")
{
custControlCountID++;
}
for (int i = 0; i < custControlCountID; i++)
{
RejRow customControl = (RejRow)LoadControl("~/RejRow.ascx");
customControl.ID = "rejRow" + i;
divHolder.Controls.Add(customControl);
}
}
Viewstate is enabled for both the text box and drop down list.
As I am using the same ID while adding the controls in Page_Init, why the controls are not getting the values from viewstate?
I think the only problem is that you have you're databinding the DropDownList on every postback from Page_Load. Just check the IsPostback-property, e.g.:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
ddl_RRC.DataSource = dicRC_Desc;
ddl_RRC.DataTextField = "value";
ddl_RRC.DataValueField = "key";
ddl_RRC.DataBind();
}
txtRC.Text = Request.Form[txtRC.UniqueID]; //To retain the value of text box
}
However, i'm not sure why you need to set the TextBox.Text property from the form-fields since it should store it's Text also in ViewState.
I have an ASP.NET page where I dynamically create over 1000 textboxes. The initial creation and display of the page works fine, however when I do a posback I find that the control state (Text) is only restored for the first 997 textboxes. The Text proprty for all the other textboxes is not restored during the postback.
I am not seeing any errors - I just see that the textboxes are blank.
Has anyone else encounted this problem. Is there something special I need to do on a page that has a large number of controls or large viewstate ?
Here is some code to demonstrate.
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
void CreateTextBoxes(bool load)
{
for (int i = 0; i < 1200; i++)
{
TextBox txt = new TextBox();
txt.ID = string.Format("{0}", i);
div.Controls.Add(txt);
if (load)
txt.Text = string.Format("Count {0}", i + 1);
}
}
protected override void CreateChildControls()
{
CreateTextBoxes(!this.IsPostBack);
base.CreateChildControls();
}
}
Add the following key to your web.config under the appSettings element if you have more than 1000 controls on a form, and set the value appropriately:
<add key="aspnet:MaxHttpCollectionKeys" value="2000"></add>
See this post for more details:
http://blogs.msdn.com/b/paulking/archive/2012/01/16/using-an-http-module-to-assist-in-adjusting-the-value-of-aspnet-maxhttpcollectionkeys-imposed-by-ms11-100.aspx
Situation: I have several Gridviews on one page, and each Gridview has a dynamically created row to display the totals at the bottom. In each case, the totals row is created on a RowDataBound event. The strategy that I am using is like the one provided by Mike Dugan on his Blog.
The following is the code for one of the GridViews, but the others all do something very simular.
protected void gvWorkerHours_RowDataBound(object sender, GridViewRowEventArgs e)
{
// Keep running total of hours.
if (e.Row.RowType == DataControlRowType.DataRow)
{
totalBillableHours += Convert.ToDouble(DataBinder.Eval(e.Row.DataItem, "Hours"));
}
if (e.Row.RowType == DataControlRowType.Footer)
{
int numColumns = gvWorkerHours.Columns.Count;
int hoursIndex = 4; //5th column, 0-based
int rowIndex = gvWorkerHours.Rows.Count + 1;
CreateTotalRow((Table)e.Row.Parent, rowIndex, totalBillableHours, hoursIndex, numColumns);
}
}
private void CreateTotalRow(Table table, int rowIndex, double totalValue, int totalIndex, int numColumns)
{
TableCell[] cells = new TableCell[numColumns];
for (int i = 0; i < numColumns; i++)
{
TableCell cell = new TableCell();
Label label = new Label();
label.Font.Bold = true;
if (i == 0)
{
label.Text = "Total";
}
else if (i == totalIndex)
{
label.Text = totalValue.ToString();
}
else
{
label.Text = "";
}
cell.Controls.Add(label);
cells[i] = cell;
}
GridViewRow row = new GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal);
row.Cells.AddRange(cells);
table.Rows.AddAt(rowIndex, row);
}
Problem: If a user clicks on an edit/delete command for any row on any of these Gridviews, it will make the totals row disappear for all other Gridviews. As I understand, this is because a PostBack is occurring, however the RowDataBound events will not occur for the other GridViews, rather they will just reload their data from the ViewState, which does not contain the totals.
Failed attempts at solving: I cannot simply call DataBind on each of the GridView during a PostBack, because that will prevent the update/delete from occurring. Although the RowCreated event will occur for the GridViews during a PostBack, this event in not sufficient because the GridViews will not have data bound and will throw an exception when I try to calculate the total. Disabling the ViewState for these GridViews seems like a solution, however there will be a lot of data to reload each time a user clicks a command. Manually saving my data to the ViewState also seems like a solution, but there does not seem to be a simple way to have the GridViews retrieve this custom data on a PostBack.
Is there any way to actually achieve what I am trying to do with ASP.NET? It seems like a simple requirement to have a totals row at the bottom of each GridView.
Thanks in advance for any help.
What if you try creating the dynamic row using the gridView.OnPreRender event instead of the gridView.RowDataBound event. This way your data you need to calculate your dynaimic row results is available but the html has not been sent to the web browser yet. Please post some more code so we can provide more insight into fixing your issue.
As recommended, I tried putting the code to create the totals row in the PreRender event rather than the RowDataBound event. This seemed to work, except that it broke all of the commands for the GridView that it was used on. It appears that manually changing the GridView disrupts its automatic behavior.
protected void gvWorkerHours_PreRender(object sender, EventArgs e)
{
double total = 0;
int numColumns = gvWorkerHours.Columns.Count;
int hoursIndex = 4; //5th column, 0-based
int rowIndex = gvWorkerHours.Rows.Count + 1;
foreach (GridViewRow row in gvWorkerHours.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
Label label = (Label)row.FindControl("lblHours");
total += Convert.ToDouble(label.Text);
}
}
CreateTotalRow((Table)gvWorkerHours.Rows[0].Parent, rowIndex, total, hoursIndex, numColumns);
}
OK, the way I ended up solving this was with JQuery. If anybody else is facing a similar problem, remember that the totals must be calculated when the DOM is ready, as well as at the end of any postback. To handle the postback situation, you can just call the Javascript on the client using ScriptManager.RegisterStartupScript().
Again, I had four GridViews in my circumstance, but I'll just show the JQuery code for one of them:
$(document).ready(function () {
setTotals();
});
function setTotals() {
var totalHours = getBillableHoursTotal();
if (isNaN(totalHours)) totalHours = '...editing';
$('#spanBillableHoursTotal').html(totalHours);
//... etc.
}
function getBillableHoursTotal() {
var total = 0.0;
var rows = $('table[id*="_gvWorkerHours"] tr.RegularRows');
$(rows).each(function () {
total = total + parseFloat($(this).children('td').children('span[id*="lblHours"]').html());
});
return total;
}
And for the C# on the code behind:
protected void Page_Load(object sender, EventArgs e)
{
// ... preceeding Page Load code
if (IsPostBack)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "?", "setTotals()", true);
}
}
I am doing custom paging for a datalist.Below method gets the required page numbers.
My problem is the click event is not being fired during debug.
Can anyone tel where the problem is.
private void BindPageNumbers(int TotalRecords)
{
int counter = 0;
for(int i=0;i<TotalRecords;i=i+5)
{
counter=counter+1;
LinkButton lnk = new LinkButton();
lnk.Click += new EventHandler(lbl_click);
lnk.ID = "lnkPage" + (counter).ToString();
lnk.Text = (counter).ToString();
pages.Controls.Add(lnk);
Label spacer = new Label();
spacer.Text = " ";
pages.Controls.Add(spacer);
}
}
void lbl_click(object sender, EventArgs e)
{
LinkButton lnk = sender as LinkButton;
int Currentpage = int.Parse(lnk.Text);
ListDataBinding_paging(2, this.Days, (Currentpage-1)*5, 5);
}
Here "ListDataBinding_paging" is the method from where the datalist is being filled.
You are creating your page link buttons dynamically. So they need to be re-created in every post-back early in the life-cycle. I suspect that BindPageNumbers is getting called after the post event data is processed and hence the click event does not get generated.
I suggest you to invoke BindPageNumbers in page_load for creating your buttons early in the life cycle. You can store the total records count in the view-state. If page_load doesn't help then try LoadViewState override - put the code after call to base implementation - something like
protected override void LoadViewState(Object savedState)
{
base.LoadViewState(savedState);
BindPageNumbers((int)ViewState["TotalRecords"]);
}
I'm creating a fileupload control on a linKbutton click event. First time it's creating the controls, but if I press the link button second time, it's not creating. What is the problem with that? The following is my code:
protected void LinkButton1_Click(object sender, EventArgs e)
{
newattach();
}
private void newattach()
{
int i;
for (i = 0; i < 2; i++)
{
count++;
FileUpload f1 = new FileUpload();
f1.ID = "fileupload" + count.ToString();
f1.Height = 34;
f1.Width = 212;
Panel1.Controls.Add(f1);
}
}
and count is a static variable. Please help.
When you create controls dynamically with ASP.NET you need to recreate the control every time you post back, generally you recreate the control on Page_Load. That is most likely the cause of your problem.