Here\'s my issue. I have a usercontrol that I want to allow users to add as many instances of as necessary using a button click (each time a button is clicked, I want to ad
I had a nightmare of a time trying to pull this off on an old project. In the intermediate time, I've discovered that I know a lot less about web development than I thought (reading this website is a great way to humble yourself on a daily -- if not hourly -- basis). In that project, Page.IsPostBack was totally useless to me because I had dynamically instantiated the controls.
That being said, the best thing I can suggest is to consider using the Session variable. If you have a class (or a collection of a class) that represents the data you capture from the page, then perhaps it'd be easiest to store values in that class/collection to improve code readability, and then write it out to the Session.
Look at your PageLoad
and add if(!this.IsPostBack)
before the line where you clear the panel.
this is of course just a guess, but I have seen many questions where the problem was related to this.
It's an ugly solution if you have a ton of users, but you could stick the usercontrols themselves into the session. I do this with my footer control because I don't want to hit the db every time the page changes to recreate the footer.
This solutions can get really tasking on the server if you have a lot of users and they use this feature a lot. At least I think it will...
But you can just repopulate your placeholder that has the usercontrols in it on page_load. I can put up an example shortly.
Example of what I do:
if (Session["footer"] == null)
{
Session["footer"] = new Footer(LinksRules.BuildFooterLinks((int)WebSiteSections.Main));// where Footer is my control
}
footerPH.Controls.Add((Footer)Session["footer"]);
Like a singleton pattern sort of...
So as I see it you could do this on anything that will cause a postback
Session["DynamicControls"] = PlaceHolder.Controls;
and in the page-Load method you could:
foreach(var control in (List<Controls>)Session["DynamicControls"])
{
yourPlaceHolder.Controls.Add(control);
}
and if the session object is null just add a single one like they've never been there..
I believe this will hang on to the data inside the controls like you want.
Since you're programmatically adding controls to your page, you'll need to recreate them on EACH postback.
Also, it's necessary that you recreate programmatically added controls on PreInit
or Init
event of the page. This is for proper viewstate restoring event management.
If you don't do this, control will be gone on postback and they won't handle any event.
EDIT
Although is recommended to add dynamically controls on PreInit
or Init
it's true (as Dustin Hodges says) that it may work if you add them on page_load
. I'd say you should avoid it unless you have no other option.
You may be able to get away with loading your controls in the Page_Load event handler and maintaining the view state properly.
It all depends on whether or not you are setting any properties of the dynamically loaded controls programmatically and, if so, when you're doing it relative to the Controls.Add(dynamicControl) line.
A thorough discussion of this is a bit beyond the scope of this article, but the reason it may work is because the Controls property's Add() method recursively loads the parent's view state into its children, even though the load view state stage has passed.
Source MSDN
this will help you
http://www.codeasp.net/blogs/SumitArora/microsoft-net/841/value-of-dynamic-textbox-lost-on-postback
you read this also
http://www.codeasp.net/blogs/Vinz/microsoft-net/256/links-to-read-before-working-on-dynamic-controls-in-asp-net
Thanks
Asif
If you are keeping track of the number of controls the user has added you need to recreate the controls the user added previously, preferably in Page_Init or Page_Load. Add something like this to that handler:
for(int i=0; i<NumberOfControlsUserHasAdded; i++)
{
//todo: change this to the appropriate user control
TextBox tb = new TextBox();
tb.ID = "tb" + i.ToString();
//todo: add to appropriate control collection
this.Controls.Add(tb);
}
If you do it this way, the state of the controls should be maintained because when you add the tb control to a controls collection it plays catch up with events and should automagically restore its viewstate.
You shouldn't have to keep track of their state in session as in most cases it will be stored in the viewstate for you