ASP.NET control event order/lifecycle
This is a very concise reference for the order which events are fired when you subclass a control. The longer more detailed MSDN page on the lifecycle can be found here. The particular control this came from was a subclassed CompositeControl, but this could be any control, or a page.
OnInit: 1
LoadViewState: 2
CreateChildControls: 3
OnLoad: 4
ShowButton: 5
OnPreRender: 6
Render: 7
OnUnload: 8
The code that produced this is below. The list above was produced after a button press on the form. This button pressed called the ShowButton() method below.
int count = 1;
protected override void RecreateChildControls()
{
System.Diagnostics.Debug.WriteLine(string.Format("RecreateChildControls: {0}",count++));
base.RecreateChildControls();
}
protected override void OnInit(EventArgs e)
{
System.Diagnostics.Debug.WriteLine(string.Format("OnInit: {0}",count++));
base.OnInit(e);
}
protected override void OnLoad(EventArgs e)
{
System.Diagnostics.Debug.WriteLine(string.Format("OnLoad: {0}",count++));
base.OnLoad(e);
}
protected override void OnPreRender(EventArgs e)
{
System.Diagnostics.Debug.WriteLine(string.Format("OnPreRender: {0}", count++));
base.OnPreRender(e);
}
public void ShowButton()
{
System.Diagnostics.Debug.WriteLine(string.Format("ShowButton: {0}", count++));
}
protected override void OnUnload(EventArgs e)
{
System.Diagnostics.Debug.WriteLine(string.Format("OnUnload: {0}", count++));
base.OnUnload(e);
}
protected override void Render(HtmlTextWriter writer)
{
System.Diagnostics.Debug.WriteLine(string.Format("Render: {0}", count++));
base.Render(writer);
}
protected override object SaveControlState()
{
System.Diagnostics.Debug.WriteLine(string.Format("SaveControlState: {0}", count++));
return base.SaveControlState();
}
protected override void LoadViewState(object savedState)
{
System.Diagnostics.Debug.WriteLine(string.Format("LoadViewState: {0}", count++));
base.LoadViewState(savedState);
}
There is also an equivalent lifecycle chart for AJAX.
Here's a few gotchas that have gotcha'd me:
OnInit() is called before the ViewState is loaded, so if you need the values of the controls after postback, this isn't the event.
OnLoad() is called before your control events on the page are fired. So if you have a button with an event handler and that changes your control, any OnLoad logic for properties of the control will be overwritten.
CreateChildControls() is not guaranteed to be 3rd as show above. It may be called at any stage as the MSDN docs state.
- If you put rendering code in
PreRender() and a method in your control that is called by a button event (or any event) relies on a control created in PreRender(), you'll get an exception. The control won't have been created until after that event has fired.
- Put the properties of the control that need persitance inside the
ViewState, not just a backing field (example below). It might seem an obvious point but can cause headaches.
public int CurrentPage
{
get
{
int val;
int.TryParse(ViewState["CurrentPage"].ToString(), out val);
return val;
}
set
{
if (value < 0)
value = 0;
else if (value >= MandarinForm.Pages.Count)
value = MandarinForm.Pages.Count - 1;
ViewState["CurrentPage"] = value;
}
}
Last updated on 09 September 2009
Comments
blog comments powered by