Say I have 5 buttons on a page, numbered 1-5.
When one is clicked, a value with a viewtate getter/setter assigns this the value of the button clicked.
If I am checking for a value in Page_Init() / OnInit(), after the postback has occured, the value will always be empty/null.
Is this correct?
If so, is there anything else I can do that doesnt require an architectural change? Or something similar I can use to persist changes across post backs (Session[] no good unfortunately).
ViewState stores the state of the page (page and control settings + custom values stored in ViewState) between post backs. It is just hidden field with serialized (and encrypted) state data. When you set something to ViewState in code behind it is transfered with page markup to the client and posted back to the sever in the next Postback. The page life cycle (between InitComplete and PreLoad) deserializes state from ViewState. That is the reason why you can't access data from ViewState in OnInit.
refer to :http://code.google.com/p/citiport2/wiki/All_Events
Page: AddParsedSubObject
Page: CreateControlCollection
Page: AddedControl
Page: AddParsedSubObject
Page: AddedControl
Page: ResolveAdapter
Page: DeterminePostBackMode
Page: PreInit
Control: ResolveAdapter
Control: Init
Control: TrackViewState
Page: Init
Page: TrackViewState
Page: InitComplete
Page: LoadPageStateFromPersistenceMedium
Control: LoadViewState
Page: EnsureChildControls
Page: CreateChildControls
Page: PreLoad
Page: Load
Control: DataBind
Control: Load
Page: EnsureChildControls
Page: LoadComplete
Page: EnsureChildControls
Page: PreRender
Control: EnsureChildControls
Control: PreRender
Page: PreRenderComplete
Page: SaveViewState
Control: SaveViewState
Page: SaveViewState
Control: SaveViewState
Page: SavePageStateToPersistenceMedium
Page: SaveStateComplete
Page: CreateHtmlTextWriter
Page: RenderControl
Page: Render
Page: RenderChildren
Control: RenderControl
Page: VerifyRenderingInServerForm
Page: CreateHtmlTextWriter
Control: Unload
Control: Dispose
Page: Unload
Page: Dispose
Page: Init is earlier
I'm not 100% sure what you're asking here, but it sounds like a problem with the ASP.NET Page Lifecycle. It trips up everyone!
Basically, what happens is that a developer expects to be able to do some work in Page_Init (or more commonly Page_Load), but the click event for whatever triggered the postback hasn't happened yet.
In fact, iirc ViewState hasn't even been deserialized when Page_Init fires.
I can't tell you where the right place to do whatever work needs done is without knowing more, but you probably want to move some of that code that's in Page_Init into an event handler later in the lifecycle.
You can see this for yourself: Pop a breakpoint at the start of Page_Init, and another one at the start of MyButton_Click, you'll see that Page_Init fires first.
You can use Request.Form["idofbutton"] to get the posted value. This happens as part of the http protocol. Inspect the http request/ response in something like firebug to see what is getting posted.
Related
Why we set master page in Page_Init event. We have other events in page.
For me one reason could be that master page does not have Pre_Init and other could be that Init of Page occurs before master page Init. Correct me if I'm wrong.
Master page is a UserControl. During Page.Init event, all the controls on the page are initialized(Control.Init is called). That's why the master page needs to be applied in Page.PreInit
Masterpage doesn't have PreInit method.
Master pages inherits:**System.Web.UI.MasterPage** and as per the design of this MasterPage class no such PreInit event is defined for this class.
Master pages are derived from Control class as seen in below hierarchy:
System.Object
System.Web.UI.Control
System.Web.UI.TemplateControl
System.Web.UI.UserControl
System.Web.UI.MasterPage
Therefore as can be guessed now, Master pages behave and in essence are treated like a control and have events similar to other asp.net server control
Because all things that 'dynamically' modify page controls have to occur there. This is where the page is rebuilt (form objects) with out request. Then things like page_load occur, after all objects are made.
Winforms analogy - if you are familiar with that - page_init is analogous to the InitializeComponent in the New (NOT REALLY SAME - just analogy please).
Only due to the nature of the web (at least round-tripping to the server), it can't possibly work like winforms (or WPF or even a SPA web app with a js/DOM UI and webapi backend) so has to rebuild the form's objects EVERY request.
Why does only the PAGE have page_init and not master page? Well as prateek says, but in addition, the rebuild of the page has to be control from just one spot. There is just one request. Controls can init, too as the page init process calls them in turn.
You have asked a question with a complicated answer.
Here is a good chart of what's going on...
http://www.codeproject.com/KB/aspnet/ASPDOTNETPageLifecycle.aspx
(source: codeproject.com)
Note how the postback data is loaded into the controls BEFORE the page_load, too - this is why it's too late to do anything big in the page load. You can't possibility get anything back from the user that was changed there (unless you go right to the postback data). The picture shows how ASP tries to 'fake' an event - driven UI on a client/server web architecture (e.g., 'event related logic' calls your 'events'). There is no such thing in client/server asp UI!
As a master page is the default screen throught the application ,it should be initialized first before the child pages.In order to get initalized earlier it is done in pre_init where the master page is loaded.later in Init() all the child pages are loaded regarding to that master page.
During the ASP.NET page life cycle, the initialization is also included on the master page. This is where the design and all the controls that are on the master page will be available before the page is loaded, which will be the "Load" phase of the page life cycle. If the master page is not initialize, you would get a page with no design, except the information on the page.
"During page initialization, controls on the page are available and each control's UniqueID property is set. A master page and themes are also applied to the page if applicable. If the current request is a postback, the postback data has not yet been loaded and control property values have not been restored to the values from view state."
https://msdn.microsoft.com/en-us/library/ms178472.aspx
I am using the session object to store success/error messages based on user actions.
On each postback, the message is set on ItemCommend and retrieved on the Page_Load of the master page. Once retrieved, the message is deleted from the session.
The problem is that the master page's Page_Load gets called before the ItemCommand gets called so the message does not show up until the next refresh or postback.
How is this situation normally handled? Is there some other event we can code against?
It is normal behavior of aspx and master pages. First of all content page's page load get fired after that Master Page's pageload get fired and then all other click etc.
You can use PageLoad Complete event to Solve your problem.
this is a normal behavior. show your message on itemcommand or Page_prerender
Create a Public Method in Code Behind of your master page like this:
public void Set_Value(String SessionValue)
{
//your code here
}
In aspx File of your content Page, Use following Line of code:
<%# MasterType VirtualPath="~/MasterPage.master" %>
Now in Code Behind of your Content Page, You can easily call Master Page's method in Item event of your any Control. In your Master Page's method you can write your required code to update and show values.
Call Master Page's Method on Content Page Like this:
this.Master.Set_Value(Session["abc"].ToString());
Is it possible to rebind a repeater (inside master page) from content page?
My pages are base on master and content pages and I have some links (anchors) for download files!
After click on those links page_load of content page fires, and will show download window. But we will never get page_Load of master page and in master page I have a summary for showing download counts.
How can I rebind that summary (inside master page) from content page before showing download window?
Yes, it's pretty simple. You can 'find' the control from the content page.
Here's a sample where i'm binding to a GridView control.
Master:
<asp:GridView runat="server" ID="gridViewMaster" AutoGenerateColumns="true" />
Content Page:
var gridView = (GridView) Master.FindControl("gridViewMaster");
gridView.DataSource = dt;
gridView.DataBind();
Just replace the grid view object and control id with your repeater...and bind it to whatever object you want.
Edit - Here's the code to find a server side div:
var divMaster = (System.Web.UI.HtmlControls.HtmlGenericControl)Master.FindControl("divMaster");
divMaster.InnerHtml = "<h2>Hello World</h2>";
Yes. You have access to the master page from your web form—using this.Master—which you'd then have to cast as the appropriate type. From there you can access any public methods or properties you've defined.
Simple add a ReBind method there that does what you want, and you should be good to go.
EDIT
It would be something like:
(this.Master as WhateverTypeYourRealMasterPageIs).ReBind();
You can expose the master page control to the children. Make the control public with an accessor in the master page... such as:
public Repeater MasterpageRptr {get;set;}
Then on your child page, add the MasterType definition:
<%# Page Language="C#" Title="Content Page" MasterPageFile="~/MyMaster.master"%>
<%# MasterType TypeName="MyMaster" %>
(where MyMaster is the master page class file)
Then you can call this in your child code-behide using the accessor.
.
.
Please vote if helpful.
The proper way to do so is for the user control to fire an event that the Master page subscribes to. Let me know if you need some sample code
Some sample code:
In your user control, add the following event:
public event EventHandler RefreshRequested;
The user control will throw this event whenever it wants a refresh by calling the following method:
private void OnRefreshRequested()
{
//make sure the event is being listened to. no point raising an event if no one cares!
if (this.RefreshRequested != null)
{
this.RefreshRequested(this, EventArgs.Empty);
}
}
Now, the master page will subscribe to the user control's event and acts accordingly. Subscribing to the event is just like subscribing to any other event (ie: Button_Click).
Let me know if this clears things up.
How can I access a control on page a.aspx from a webusercontrol.ascx
I do not know the technical term used to describe this, if any,
the webusercontrol.ascx page contains a button.
onclick of the button, placeholder on main page must display the "required content".
if this were on the same page no problem.
but how to access across pages?
Expose an event on your ASCX control, subscribe an event handler method on the ASPX page to the event on that page's instance of that control, implement the method to make the required changes to the parent page.
I cretated my own server control (a dropdownlist) and thus my own LoadViewState and SaveViewState methods. When is the LoadViewState called? I added the control to my page and looked when the methods are called. Only the SaveViewState is called when the page is requested, LoadViewState is not. Do I have to call it manually?
Thanks :)
The diagram on this MSDN page of the ASP.NET page lifecycle is an excellent reference to have on-hand for these sorts of questions (it's printed out and taped on my cube wall right now).
As you'll see on the diagram, LoadViewState for a control is called after the page's Init, and before the page's PreLoad; it is called only on postback, not on initial page load.
A control's SaveViewState is called after the page's PreRenderComplete, but before the actual Render.
After Init, but before Load. LoadViewState does not run on the initial page load, but subsequent page loads. No need to when no state exists. No you do not need to call manually. You just need to worry about the data you want to save, and reloading that data during the loading phase.