Enabling view state is not working with controls in web part - asp.net

What I have?
I have a simple web part which has a Table. The table has two controls, a TextBox and a Button. In CreateChildControls() method, I add the controls to table if !Page.IsPostBack is true. And, table has view state enabled.
What I want to do?
I want the controls in the table to be present after the post back.
What problem am I facing?
I except the the controls, TextBox and Button to be present in the table after the post back. But it is not happening.
I feel building the whole table in every post back is little costly and enabling view state will solve this problem.
Can anyone tell if I am missing something?
Thanks in advance!
Update:
I tried setting EnbleViewState property of web part. Still the same result.
Code:
public class TreeWebPart : Microsoft.SharePoint.WebPartPages.WebPart
{
private Table table;
private Button clickMe;
private TextBox content;
protected override void CreateChildControls()
{
base.CreateChildControls();
BuildTable();
}
private void BuildTable()
{
table = new Table();
clickMe = new Button();
content = new TextBox();
table.ID = "myTable";
table.EnableViewState = true;
if (!this.Page.IsPostBack)
{
clickMe.Text = "Click Me!";
clickMe.Click += new EventHandler(clickMe_Click);
content.Text = "Click button to set text";
content.Width = Unit.Pixel(200);
TableCell cell = new TableCell();
cell.Controls.Add(content);
TableRow tr = new TableRow();
tr.Cells.Add(cell);
table.Rows.Add(tr);
cell = new TableCell();
cell.Controls.Add(clickMe);
tr = new TableRow();
tr.Cells.Add(cell);
table.Rows.Add(tr);
}
this.Controls.Add(table);
}
protected void clickMe_Click(object sender, EventArgs e)
{
content.Text = DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString();
}
}

Since the view state only persists changed control state across postbacks, and not the actual controls themselves, dynamically added controls must be added to the ASP.NET Web page, on both the initial visit as well as all subsequent postbacks. For more information visit Here.

Related

Capturing the value of dynamically created TextBox and DropDownList in ASP.NET

I am stuck in an issue, tried googling but could not find any solution.
I have created controls dynamically in Page_Load and I have a static button.
When the button is clicked, I need to capture user entry in those controls.
Now when I am trying to access the control using its unique id, error is being returned as the control is not available at runtime. :(
For loop - starts
if (dr["Type"].ToString().Trim() == "DropDown")
{
DropDownList ddl = new DropDownList();
ddl.Id = "ddl" + Convert.ToString(Counter);
ddl.DataTextField = "Text";
ddl.DataValueField = "Value";
ddl.DataSource = ds1;
ddl.DataBind();
ddl.EnableViewState = true;
cell.Controls.Add(ddl);
}
else if (dr["QuestionType"].ToString().Trim() == "TextBox")
{
TextBox txt = new TextBox();
txt.ID = "txt" + Convert.ToString(Counter);
txt.EnableViewState = true;
cell.Controls.Add(txt);
}
row.Cells.Add(cell);
table.Rows.Add(row);
Even if i do a FindControl in Btn_click function, it says that the panel has 0 controls.
var textbox = (TextBox)pnlMidTermFeedback.FindControl("txt5");
textbox is always NULL, although I have a control txt5. I can see it when I do a F12.
Please help.
Dynamically created controls must be recreated on every postback:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Set values and properties of controls specified in markup
...
}
// Create new controls and add them to the panel
...
}
They will then be available in the button event handler, and contain the data entered by the user.

ASP.NET / Sharepoint - Checkbox.CheckChanged event fires same Event of other (same) control from bevore

I'm working on a Webpart for SharePoint with ASP.NET
On every click my page will be reloaded and I add a List of Checkboxes with different ID's in two tables and a event to handle the CheckedChanged Event (all the same).
In Addition the autopostback is set to true.
When I run and click my first checkbox every thinks work fine.
By clicking the next checkbox in the same table, I get in my eventReceiver 2! Events - first, the right one and after that the checkbox was clicked before.
As many boxes I click, as many checkboxes fire their Event (when used before).
Only difference is between the 2 Tables. Here clicking in first table all is ok, clicking in second table all ok... after that each table has the same effect. Click in first table again, I get 2 Events to handle, click in the second one these 2 to handle.
I have no idea what's going wrong.
Here's some code
CheckBox eMailNotifikation = new CheckBox() { TextAlign = TextAlign.Right };
eMailNotifikation.ID = #anCounter + "_" + #anName + "_" + #anothername + "_" + "mail_checkbox";
eMailNotifikation.AutoPostBack = true;
eMailNotifikation.CheckedChanged -= new EventHandler(eMailNotifikation_CheckedChanged);
eMailNotifikation.Checked = #setInitialValue;
//Add Event
eMailNotifikation.CheckedChanged += new EventHandler(eMailNotifikation_CheckedChanged);
cell.Controls.Add(eMailNotifikation);
that's it for creation
here's my receiver:
void eMailNotifikation_CheckedChanged(object sender, EventArgs e) {
CheckBox eMailNotification = (sender as CheckBox);
//Do some... calling a Webservice
eRoomWebservice.DoMyTasl(<params>);
}
the tables are only build with new... and ID.. nothing Special
EDIT::::
I've build the code in easy ASP.NET and there it is working, maybe this is a SharePoint Issue
protected void Page_Load(object sender, EventArgs e) {
Table test = new Table();
test.ID = "test1";
TableHeaderRow thr = new TableHeaderRow();
TableHeaderCell thc = new TableHeaderCell();
thc.Text = "Checkboxes";
thr.Controls.Add(thc);
test.Controls.Add(thr);
TableRow tr = new TableRow();
for (int i = 0; i < 10; i++)
{
TableCell tc = new TableCell();
CheckBox chb = new CheckBox();
chb.ID = "Some_" + i;
chb.AutoPostBack = true;
chb.CheckedChanged += new EventHandler(TestEH);
tc.Controls.Add(chb);
tr.Controls.Add(tc);
}
test.Controls.Add(tr);
root.Controls.Add(test);
}
void TestEH(object sender, EventArgs e) {
CheckBox chbx = sender as CheckBox;
string text = chbx.ID;
}
i found out wha'ts the Problem on my posted issue.
Content of the attribute ID="" was too Long, after shrinking the IDName it was working again.
Strange but it was the solution,
Remember: Watch out how Long Content of the Attribute ID is, there must be a Limit somewhere

Get control which is generated on runtime

am creating some TextBoxes by backend on a text change event, Like this :
protected void txtHowMany_TextChanged(object sender, EventArgs e)
{
int totalSections = Convert.ToInt32(txtHowMany.Text.Trim());
for (int i = 1; i <= totalSections; i++)
{
TextBox tbx = new TextBox();
tbx.Text = "";
tbx.ID = "section" + i;
tbx.Style.Add("width", "90%");
tdSectionsAdd.Controls.Add(tbx);
}
trSectionsName.Visible = true;
}
The auto post back is true for txtHowMany, so when I enter a number, it generates the textboxes and add it to table division
Now the problem is, I am trying to get text from generated textboxes like this :
protected void btnSave_click(object sender, EventArgs e)
{
int numbersOfSectionsToSave = 1;
int sectionsToSave =Convert.ToInt32(txtHowMany.Text.Trim());
for (int i = 1; i < sectionsToSave; i++)
{
Sections section = new Sections();
section.CourseId = result;
section.OrganizationId = course.OrganizationId;
foreach (Control c in tdSectionsAdd.Controls)
{
if (c.GetType() == typeof(TextBox))
{
TextBox txtBox = (TextBox)c;
string id = "section" + i;
if (txtBox.ID == id)
{
section.Name = txtBox.Text.Trim();
}
}
}
string name = Request.Form["section1"];
section.CreatedBy = "Admin";
section.CreationDate = DateTime.Now;
section.ModifiedBy = "Admin";
section.ModificationDate = DateTime.Now;
numbersOfSectionsToSave += section.SaveSection();
}
But its showing 0 count for the controls in tdSectionsAdd , The controls are added before I am trying to access them, but still it shows no controls in td.
Please help, How can I get these textboxes?
Thanks!
You need to add them in each postback. Store the totalSections variable in ViewState so you can add them i page load also:
protected void AddTextBoxes()
{
int totalSections;
if (int.TryParse(Convert.ToString(ViewState["TotalSections"]), out totalSections)
{
for (int i = 1; i <= totalSections; i++)
{
TextBox tbx = new TextBox();
tbx.Text = "";
tbx.ID = "section" + i;
tbx.Style.Add("width", "90%");
tdSectionsAdd.Controls.Add(tbx);
}
trSectionsName.Visible = true;
}
}
protected void txtHowMany_TextChanged(object sender, EventArgs e)
{
ViewState["TotalSections"] = Convert.ToInt32(txtHowMany.Text.Trim());
tdSectionsAdd.Controls.Clear();
AddTextBoxes();
}
protected void Page_Load(object sender, EventArgs e)
{
AddTextBoxes();
}
Dynamic Created controls "Disappear" on postback, if they are not "recreated" in the Page_Init of that page.
Only if they are created in the page_init will the page's viewstate get updated with their information.
Long Explantion:
When we perform a postback (or partial postback) we want to be able to access those controls (or at least the values the user put into them).
We know that the data is in the viewstate, but ASP.NET doesn’t really know which control a ViewState item belongs to. It only knows to match a viewstate item and a control through the same index (e.g. Matches item n in the viewstate tree to item n in the control tree). Therefore in order to get the dynamic controls' data, we need to re-create the controls each time the page is postbacked.
BUT in order for this to work, we need to re-create the controls in the Page_Init function NOT in the Page_Load.
Why? Because when the ViewState is created it needs all the controls to already exist.
This is taken from MSDN, as you can see the viewstate is loaded AFTER the init but before the page load.
TL;DR Call the function that creates the dynamic controls in the page_init and you should be able to see all the values the user entered when the page postbacks
A few links on this issue:
http://forums.asp.net/t/1186195.aspx/1
ASP.NET - Dynamic controls created in Page_Pre_init() or Page_Init() or Page_Load()
Option 2:
I should note: If the controls all had unique Ids and you're not interested in re-creating them again every postback - you could always look for them in the Request Object.
The Request.Form is a NameValueCollection that holds the values of all the controls that were part of the form, just search it for whatever you're looking for

ASP.Net Textbox value lost during postback when you have a very large number of Textboxes on page

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

datalist custom paging in asp.net

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"]);
}

Resources