I've read several articles on this issue, and technically speaking, all they end up doing is taking html code from a user control and injecting it into the containing page. I want a true user control to be loaded on to the page, so that on postback, I still have access to that loaded user control and I can validate fields on it on server side, etc. etc. What I mean to say is that once the user control has been loaded onto the page using ajax, it should there after act like it was originally created as part of page life cycle when the page was first loaded. Does that make sense? Any ideas on how to do this? UpdatePanel may be a solution, but I'd rather not use that.
Update panel is the solution since you need it to update the page's ViewState so that the newly added usercontrol needs to be part of the page lifecycle. Also, when the page does post back, you need to remember that it was added and re-add it so that the control structure gets re-created properly.
When you dynamically create user controls, you have to make sure to bind to the elements. Look into http://docs.jquery.com/Events/live
Related
We have a site where all pages are output cached, i.e. the caching is on aspx-level with VaryByParam="*". Now there is a requirement to make a gallup control, i.e. a small "How is this site working for you?" and then when the user clicks an answer the results are shown.
The gallup is implemented as a usercontrol that is added to the master page so gallups can be added to any page to which a gallup is created in the cms. The problem is that output cache naturally caches all clicks so when user no 2 votes he sees the results that where calculated after the first vote on that alternative.
Now I'm trying to use cache substition. I added an asp:Substition tag where the user control used to be, load the control dynamically and render it (using this approach http://coderwall.com/p/4ajzqq). The problem is that the postbacks that voting triggers is never fired. Apparently the method that the substition control executes is loaded outside the page life cycle or too late.
Any ideas?
Regards,
Mathias
I solved this by skipping the substitution control and just used the user control as normal, so the gallup/question view was output cached. Then in the click handler for the answer alternatives I added
Response.Cache.SetNoServerCaching();
which exempted the results view from output cache and hence it was updated as it should.
It is also possible to use Response.Cache.SetNoServerCaching() in Global.asax, using VaryByCustom. It merely requires sensing in Global.asax whether the page is a post-back or not. Here is a code example.
I'm working on a project where the page load certain controls depending on the index available. The loading occurs in the page load where the method PopulateSearchField is called.
Within this method, all the UserControl are added on the page using : Page.LoadControl("path");
The page load and all the required controls are on the page. My problem is when the user click on the Search button the event is triggered and a query is built based on the user input int those controls. Unfortunately, the method isn't able to produce a proper query as it is unable to find any of the controls on the page.
With a temporary ControlCollection variable, I've been able to see that the number of controls on my page is 3 when it should be something from 4 to 10. Those 3 controls in the collection are the static label and buttons on the page.
I don't know if something is wrong with the code or if it's a page cycle problem as this solution used to work on framework 1.1. Yeah, I know this isn't the best thing to do so, but they did it this way and I gotta make it work.
I'm not sure if it is the migration that has caused the problem or not.
Thanks a lot, David!
When you click the button, the controls are no longer available server side when your click handler is being processed. The page, server side, has no knowledge of the controls you created dynamically since there are no server side controls for the posted values to map to. If you want to find the values, you need to inspect the posted control data and not rely on the server side asp.net control heirarchy.
You could also write all the data you require to a hidden field via javascript and then read the hidden data server side since it will will be posted.
The following is occuring:
Creating controls dynamically
Posting controls data on click
ASP.NET maps the data to the existing controls it knows about.
Your controls are not found so the data is no mapped to anything.
You need to add your controls before the mapping occurs (in PreInit). Check out the Page Lifecycle and you will see how it ties all the controls and data together.
Are you re-adding the controls to the new page when the user clicks search?
Remember... every time the user hits your server for that page... a new Page object is created. If you're dynamically adding controls, you have to do it every time the page loads.
Additionally, since you seem to want to get values out of the controls, you're going to have to make sure that the controls are created with the exact same ID property every time, and created before viewstate is loaded, if you want them to retain their values.
I want to add more controls to page based on some specific conditions. Those controls don't need any ViewState or binding data, it is as simple as a static link.
I wonder where I could write the code: inside OnLoad or OnInit method? and why? If I place it inside OnLoad, should I add following line: if (IsPostBack) return; before any initialization code?
You can add controls in either the OnInit method or OnLoad, whether they need view state or not. (The reason why is because as soon as you add a control to the Page the control loads its view state, even if you add it after the LoadViewState stage...)
should I add following line: if (IsPostBack) return; before any initialization code?
No. It is imperative that your dynamically added controls are added to the control hierarchy on every page load, not just the initial one.
If you are going to work with dynamically-added Web controls, I strongly suggest you read these two articles:
Dynamic Controls in ASP.NET (This is actually three articles, this being the first in a series.)
Creating Dynamic Data Entry User Interfaces
For a working, end-to-end example of dynamically loading controls based on some external conditions (such as configuration in a database), see Creating a Dynamic Data-Driven User Interface.
Happy Programming!
I would suggest just adding the controls to the page statically and toggling their visibility to "True" when the conditions are met. They won't render anything to the page when they're invisible, and this will save you a lot of headaches, especially since it sounds like you're fairly new to dynamic controls.
I'm not sure I fully understand, but I'd personally put an asp:Literal on the page (or several if you need them in different places) and then create the HTML you need in the OnLoad event.
If you do that, then the html you put into that literal will be saved in viewstate, and therefor you won't have redo it on postback.
http://chetanwarade.wordpress.com/2010/08/21/asp-net-add-dynamic-control-and-retrieve-dynamic-control-value-2/
Here is code that demonstrate how to add dynamic control and retrieve dynamic control value.
I am working on a project which creates controls dynamically for a form in the page_load event, loads in their current values from the database and saves their values (using FindControl) when the user clicks the continue button.
When I added a control statically in the .aspx page and followed their same procedure of loading the value in the page load and saving it on the button press I found that the value would not save correctly. It seems that it wouldn't save because the click event fires after the page_load, so the page_load of the post back reverted the value and the user entered value was not saved.
The strange thing is that by changing the control to be dynamically created just as all the other controls on the page and keeping the loading and saving the same it now works. Even though the page load still creates the control with the old database value.
It seems like a very fundamental asp .net feature here but i'm just unclear as to what is going on. I suspect it is to do with the timing of creation and maybe when the view state kicks in.
Static page controls are created just like dynamic page controls. The difference might be coming in your Page_Load. Whenever you postback all the controls are created afresh which means they are created with their initial values. This happens because after creating the controls asp.net throws away the controls/objects.
So, when the request comes, the first thing that asp.net does it to recreate the controls by looking at their definitions (in the designer files). On each postback they are created and initialized again losing their state in the process.
But after creating the controls Asp.Net loads any viewstate that is sent along with the request which makes people think that the state is always saved at the server.
What might be happening is that either the viewstate is not enabled for your control (in case they are created in designer), in which case you may try using EnableViewState property to true of the control.
Or, when you're doing a Page_Load, you're forcefully re-initializing everything. And in process losing all the control data. If you could post the logic of Page_Load, it might get clarified.
Make sure that:
you are not setting the value again for the static control in Page_Load. The dynamic control are probably getting around it by grabbing the ViewState and form values at a different stage in the lifecycle.
The dynamic controls are added After the static control. Or at least they are added in a different container. Placement in the control's collection can affect the ViewState, although it doesn't look like your scenario / since what you mention seems to be more about the values in the current post.
The save is happening After the Page_Load in response to the corresponding event.
I've run into similar problems in the past (quite a few times actually), but what helped me the most is understanding the ASP.NET Page Lifecycle.
Microsoft has an article on it which describes it pretty well, but this post by Solomon Shaffer really cleared up everything.
I suggest reading them both and coming back with additional questions regarding to a particular state, when to load/save data etc..
Hope this helps.
Marko
Note that you may want to use Page.IsPostBack property to avoid reinitializing values on button clicks and other events.
private void Page_Load()
{
if (!this.IsPostBack)
{
// Assign values to the controls.
}
}
What choices do I have for creating stateful dynamic content in an ASP.Net web site?
Here's my scenario. I have a site that has multiple, nested content regions. The top level are actions tied to a functional area Catalog, Subscriptions, Settings.
When you click on the functional action, I want to dynamically add content specific to that action. For example, when Catalog is clicked, I want to display a tree with the catalog folders & files, and a region to the right for details.
When a user clicks on the tree, I want a context sensitive details to load in the details region (like properties or options to manage the files).
I started with UserControls. They worked fine as long as I kept loading everything into the page, and never let one disappear. As soon as one disappeared, ViewState for the page blew up because the view state tree was invalid.
(I didn't want to keep loading stuff into my page because I don't want the responses to be too huge)
So, my next approach was to replace my dynamic regions with IFrames. Then instead of instantiating a UserControl, I would just change the source on my IFrame. Since the contents of the IFrames were independent pages I didn't run into any ViewState problems.
But, I'm concerned that IFrames might be a bad design choice, but don't fully understand why. The site is not public, so search engines aren't a concern.
So, finally to my question.
What are my options for this scenario? If I choose an Ajax Solution (jQuery), will I have to maintain my own ViewState? Are there any other considerations I should take into account?
Controls that are added dynamically do not persist in viewstate, and this is the reason that it doesn't matter if you use AJAX or iframes or whatever.
One possible work-around is to re-populate controls on postback. The problem with this, is the page life-cycle (simplified) is:
Initialize
LoadViewState
Load Postback Data
Call control Load events
Call Load event
Call control events
Control PreRender
PreRender
SaveViewState
Unload
What this means is the only place to re-add your dynamic controls is Initialize -- otherwise posted data (or viewstate information) is not loaded into that control. But often, because Viewstat/postback data isn't available yet in Initialize, your code doesn't have the information it needs to figure out which controls need to be added.
The only other work-around I've found in this situation is to use a 3rd party control called DynamicControlsPlaceholder. This works quite well, and persists the control information in viewstate.
In your particular case, it doesn't seem like there are that many choices/cases. Is it practical just to have all the different sets of controls in the page, and put them inside of asp:placeholder controls, and then just set one to visible, depending on what is selected?
Some other options:
Content only appears to be dynamic. You load enough controls on the page to handle anything and only actually show what you need. This saves a lot of hassle messing with view state and such, but means your page has a bigger footprint.
Add controls to the page dynamically. You've already been playing with this, so you've seen some of the issues here. Just remember that the place to create your dynamic controls for postbacks is in the Page_Init() event, and that if you want them to be stateful, you need to keep that state somewhere. I recommend a database.
you've got a number of different options, and yes, IFrames were a bad design choice.
The first option is the AJAX solution. And with that there's not really a viewstate scenario, it's just you're passing data back and forth with the webserver, building the UI on the fly as needed.
The next option is to dynamically add the controls you need for a given post, everytime. The way this would work, is that at the start of the page life cycle, you'd need to rebuild the page exactly as it was sent out the last time, and then dump out all the unneeded controls, and build just those that want.
A third option would be to use Master pages. Your top level content could be on the Master page itself, and have links to various pages within the website.
I'm sure given enough time, I could come up with more, but these 3 appeared just from reading your problem.
dynamic controls and viewstate don't mix well, as noted above - but that is a Good Thing, because even if they did the viewstate for a complex dynamic page would get so bloated that performance would diminish to nil
use Ajax [I like AJAX PRO because it is very simple to use] and manage the page state yourself [in session, database tables, or whatever works for your scenario]. This will be a bit more complicated to get going, but the results will be efficient and responsive: each page can update only what needs to change, and you won't be blowing a giant viewstate string back and forth all the time