I have an ASP.NET user control that I'm embedding in another user control. This works fine.
I need to know the best logic/method for detecting when the control is loaded. In other words, I have some display initialization logic that needs to run when the control is initially displayed. Surely there is a pattern for this.
The typical method is to put (!IsPostBack) logic in the Page_Load method of the control. This works great until you end up with a state when the Parent page has already posted back many times. My user control gets added to the page but its display does not intialize properly.
I'm hoping to find a way that keeps this logic inside the control, versus various hacking around in the codebehind of the parent page.
See the following MS article. They have an example that places several controls within a user control and initializes them.
There is another post here on StackOverflow that seems similar. You may want to check it out, and see if it points you in the right direction.
It may also be helpful to review the page life-cycle and events.
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 using a file manager-type WebControl that does lots of postbacks. It's placed inside a Page that is relatively complex. I would like to prevent the WebControl from causing the whole Page to go through the lifecycle. An UpdatePanel helps a little, but not enough.
Is there any way to isolate the WebControl from the rest of the Page? The only way I can think of is sticking the WebControl in a separate Page and creating an iframe in the original Page. Unfortunately that also means my WebControl properties/settings are no longer in the original Page. If I want two instances of the WebControl with different settings, then I have to create a Page for each setting and reference the correct one in my iframes. Not quite as "drag & drop" as I would like. Any other suggestions?
Hard to tell, you can't prevent a control from going through lifecycle; is there anyway to identify though, that during a certain page postback, you prevent the code from running in each event handler by doing something like:
if (_shouldNotRun == true)
return;
//Event handler code
Essentially, figuring out some way to indicate whether the control should run may be an option. IFrame would work, but yes you have to deal with the issues you mentioned. Can you give more detals to the problem?
HTH.
Not 100% sure what events possible to override that are called on PostBack. A good source for the Life Cycle of a page (http://msdn.microsoft.com/en-us/library/ms178472.aspx)
But it sounds as it would be better to remake your control to create Ajax webservice requests for the functions that are possible to prevent most of the postback's?
Cheers,
Stefan
I'm writing an asp.net web app. and i've hit a bit of a brick wall.
basically i have 2 pages, the main page with a text box in and a popup that contains a treeview.
My problem is this. when i select a treeview item i want the program to perform some database transactions using asp.net and then pass the value retrieved from the database into a javascript function that passes the data back from the popup page to the parent page. My problem is that i cannot find any way of calling a javascript function from asp.net. I've tried assigning attributes to controls on page load, but this does not work as when the page loads the data has not been retrieved from the database.
Have a look at the ClientScriptManager class. You can register scripts from code-behind that will run when the HTML page loads. Those scripts can call other javascript functions on the page.
There are many tutorials and examples on the Web. Here's one I found that may help but there are many more.
How to use the client script manager
You hit the nail on the head when you said "I've tried assigning attributes to controls on page load, but this does not work as when the page loads the data has not been retrieved from the database." You just need to discover when you're pulling the data from the database, and then assign the values after that. Without looking at your code, there's no way to know for sure, but Page_PreRender is probably a good bet to assign your values...it's probably after you're pulling information from the db...it's pretty much the last place that you can make things happen before the html is generated for the client.
You can invoke a function resided in the Main Page and call that function in the Main Page from the Child Page which is your pop up window.
Please refer to these links for references
http://chiragrdarji.wordpress.com/2007/03/10/call-parent-windows-javascript-function-from-child-window-or-passing-data-from-child-window-to-parent-window-in-javascript/
http://www.webmasterworld.com/forum91/2957.htm
http://hspinfo.wordpress.com/2008/01/12/call-parent-windows-javascript-function-from-child-window/
This one helps with retrieving popups from values using javascript
http://www.eggheadcafe.com/articles/20060117.asp
This one shows how to fire a postback using javascript, and manage it in the codebehind.
http://weblogs.asp.net/mnolton/archive/2003/06/04/8260.aspx
If you put them together, and use Control.ClientID to find the actual "html name" of your asp.net controls, you'll be able to set that up in no time.
Might not be the prettiest way to do it in town, and incidentally make little baby Jesus cry, but anyway, it works.
[edit]Oh. I just saw that it seems I answered the question the other way around, or "how to trigger codebehind from Javascript". I think the method I suggest may help you, if you use it right.
The javascript of the popup should pass the information to the parent window, and the parent window function should call a postback when it receives the information.
The javascript of the popup window should be only registered on a postback with the correct information retrieved, so that when the postback occurs on the popup because of the selection of the right information, the window closes and passes the information to the parent page.
The parent page, triggering postback, does the thingies you need it to, and the app resumes "normally" from there on, doing whatever you need it to, outside of the popup page.
So I have a number of user control dynamically added to a page, and user interaction with these dynamically added user controls need to be handled by the control's parent.
Is this what is referred to as "event bubbling"?
How do I do that in VB?
Thanks in advance.
First, you have several complex issues here and my initial thought is that you should separate them and attack each on its own until you have it working and then add them into the final solution. For instance, don't try to start off by dynamically creating your user control and getting it to expose and fire an event. The dynamic part of this problem could get in the way and cause your events not to work but you would never know which is the problem. Instead my recommendation is you focus on events in VB.NET and getting them to work from a statically created user control. Then once you have this all working, move to making the user control dynamically created.
As far as understanding events in VB.NET, I highly recommend the MSDN samples. Start with this simple example: How to: Raise an Event (Visual Basic) and then follow through with the other samples that are linked to from that page. Then once you have learned creating your own events in VB.NET, then look into adding a usercontrol dynamically.
Event bubbling is when a parent control handles an event from a child. So, yes, this is what you are trying to do.
I am not sure of VB but in c# you can use following
id.event+=eventhandler yourEvent;
My first response to this kind of question is always this - why are you dynamically adding the controls? Could they go into a repeater (where this becomes a lot simpler), or must they be programatically handled?
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