In an interview question today, I was asked which is the last event in page life cycle where you can set the control's properties. I said it will be the event (eg. button click etc) or if there is no event then set it in page load event. Then he said I want the last event name.
Which is the last event to update control's properties and why would one use such an event? and not page load or button click etc?
I would say its the PreRenderComplete event, since the page is rendered immediately afterwards
Although looking at the MSDN page lifecyle, the SaveStateComplete event happens even after that. Though if you were to use that you wouldn't be able to save the control's new properties to the ViewState.
In practice personally I would use the PreRender event to do 'final' control changes.
SaveStateComplete is the last Page-based event where you can set Control properties. However, SaveStateComplete is not available in Controls themselves, and any properties set there will not be persisted in ViewState. Since the original question related to the "Page lifecycle," I think this would be the correct answer.
PreRenderComplete is the last Page-based event where you can set Control properties and have them still persisted in ViewState. As with SaveStateComplete, though, it's not available in Controls.
PreRender is the last event that's available in both Controls and on the Page where you can set properties and have them persisted in ViewState.
Related
I am using entity framework 4.0 to bind a database object to a DetailsView on an ascx control. Within the DetailsView, I have a number of asp:panels that I'd like to show/hide depending on what's happening in that person's visit.
So, the first time through the page I'm setting panelA.Visible=false in the FormView_OnLoad event, and all is well - that panel is not output in the HTML. It listens to what I'm asking here.
Once I click submit and postback, I am again checking what's going on and setting panelA.Visibe=false in both FormView_OnLoad and EntityData_OnUpdating. But this time, when the page comes up panelA is showing.
I find that I can only hide that panel after postback by setting visible=false in DetailsView_PreRender, or by binding visibility to a public variable.
I'm thinking perhaps in the life cycle the DetailsView is binding again way toward the end, and throws away my visibility settings, even though they're not bound. So to show/hide panels within the DetailsView on postback, will I always have to set visibility on DetailsView_PreRender or after?
Am I on the right track here, or is something else resetting me at the last second?
Why can I set visibility the first time through the page but not postback?
You should always make final modification of your page structure after postback processing - that is the reason why PreRender event exists. Other possible event in your scenario can be handling DataBound event but better and more clear way is PreRender.
Assume I have an asp:GridView with some customer information. On that page I also have a button which allows me to add a new user to the GridView. When I add the click the user, I databind the gridview again in the button click. Correct me if I am wrong, but if the asp.net lifecycle or at least part of it is in the following order:
page_load
Hookup event handlers such as my button click
page_preRender
Does this mean that if I put the databinding for the gridview in preRender, that is the only place I need to worry about calling it. I can remove it from the button click. This is what I think, but I am not sure if my thinking is correct, so I would like some more insight as to the benefit of putting code in PreRender as opposed to PageLoad
By PreRender, you assume that most logic in the page that would affect the binding result has been completed (usually in Page_Load, but anywhere earlier really).
Controls in the .Net framework by default do their binding in the PreRender event (makes sense, bind to the datasource at the last possible moment...could be that you changed the data 400 times earlier in the lifecycle). Here's the full layout of the 2.0 lifecycle for reference.
PreRender - Before this event occurs:
The Page object calls EnsureChildControls for each control and for the page.
Each data bound control whose DataSourceID property is set calls its DataBind method. For more information, see Data Binding Events for Data-Bound Controls later in this topic.
The PreRender event occurs for each control on the page. Use the event to make final changes to the contents of the page or its controls.
When a page is posted back, which statement runs after page_load is done executing? Without knowing what controls are in the page. This is in VS 2008 debugger.
EDIT:
The question is about knowing which event and for which control comes next.
ASP.NET Page Lifecycle
PreInit
Init
InitComplete
PreLoad
Load
Control Events (e.g. ButtonClick)
LoadComplete
PreRender
SaveStateComplete
Render
Unload
The "next statement" is indeterminate. To put it another way, in the sense of "separation of concerns", it's none of your concern. It's the concern of ASP.NET, but not of individual controls on a page, nor of individual developers debugging a page.
I recommend that you determine what question you really needed answered, and what problem you really needed solved.
Here's an example of "why not": Consider the DataBinding event, which is raised when the Control.DataBind method is called, often from inside of Page_Load. Consider a page that contains a DataGrid control. When Control.DataBind is called, the DataBinding event is raised for the control, and Control.DataBind is then called on each control in Control.Controls, eventually causing DataBinding to be raised for those controls. When it gets to the DataGrid, the control will populate its Controls collection with one row for each row in the input data.
Each of the added controls will need to "catch up". They will go through the PreInit, Init, Load, etc. phases - everything up to DataBind.
There's no way to know ahead of time which controls will be added, so you certainly can't determine which events will be fired, and in which order. In fact, some of the control events will fire or not depending on the previous state of the controls. A SelectedIndexChanged event on a dropdown control in a template column of one of the rows may fire if the dropdown index has changed from the last postback, but not if it has stayed the same!
When programmatically adding user controls using LoadControl(string path), when, in the user control's page life cycle, does it initialize its sub-controls with its viewstate?
I'm asking this question because one of my user controls that's being programmatically loaded has a TextBox control that is not being initialized/loaded by it's viewstate on PostBack on the Page_Load event (which is not the case for a regular .aspx pages and hence my confusion). Overall, I need to retrieve values from the Textbox control.
Thanks
ViewState is loaded before the Page_Load event. If you want your control to work with ViewState, you need to load it and add it to the page before that event — usually on PreInit.
The life cycle reference is here:
http://msdn.microsoft.com/en-us/library/ms178472.aspx?ppud=4
Read the description for the Pre Load event, which immediately precedes Page Load:
Use this event if you need to perform processing on your page or control before the Load event.
Before the Page instance raises this event, it loads view state for itself and all controls, and then processes any postback data included with the Request instance.
Thus by Pre Load time it's already too late. Also, the description for the PreInit event specifically mentions that it's the place to "create or re-create dynamic controls."
Is there any kind of event out there that would allow for a preload post back event.
The reason I ask is I have a control that adds sibling controls to it on postback events, however, by the time it has loaded the post back its too late to add the new control to the control collection. Therefore, the controls are never updated correctly.
Thanks!
Try the Init event.
Override CreateChildControls (make sure to call base!). In your postback event handler, make sure you are storing somewhere the list of controls that should be created dynamically, so when CreateChildControls gets invoked very early in the lifecycle on the next go-round, it will recreate the controls built on the last postback.
Here is a quick hack. You can always, query the __EventTarget and or the value of the submit button in init and can load dynamically the control.
But doing so, may not be appropriate as your control hierarchy would change and could cause problems.
As above, dynamic controls have to be added during the page Init event, so that they can be properly handled within the page's Viewstate. You might want to turn the Viewstate off for the page as well, since it can fire errors at you if the controls change.
As has already been stated the proper place to add dynamic controls is in the Init event.
Here's an article with more information.
Dynamic Web Controls, Postbacks, and View State
To get a better understanding of the ASP .NET page life cycle see:
ASP.NET Page Life Cycle Overview
This page explains the event order (and what happens in each one) in a postback, it helped me more than once.
I've just found this link, that can also be of use to you