Find out what stage of the life cycle a control is up to in ASP.NET WebForms

匿名 (未验证) 提交于 2019-12-03 00:48:01

问题:

From the outside of a control, is it possible to find out what stage of the Page LifeCycle (Init, Load, PreRender etc), a particular control or page is up to?

For example, in pseudo code:

if myControl.CurrentLifeCycle == Lifecycle.Init { do something } 

回答1:

I'm afraid there is no builtin function to check in what Page-Lifecycle phase a Page is. It is also difficult to add this functionality without handling all events in the Page itself, because some events are protected. Therefore you could also inherit the LifeCycleListener-class from Control, add it in the constructor to the page listening and override all events.

If you only need the public "phases" PreInit,Init,Load,DataBinding,PreRender,Unload,Disposed have a look at following approach(VB.Net, but i think you'll get the idea):

Public Enum LifeCyclePhase     AfterPreInit     AfterInit     AfterLoad     AfterDataBinding     AfterPreRender     AfterUnload     AfterDisposed End Enum  Public Interface ITrackingLifeCycle     ReadOnly Property GetLifeCycleListener() As LifeCycleListener End Interface  Public Class LifeCycleListener      Public Sub New(ByVal ctrl As Control)         Me._PageListening = ctrl.Page         AddListener()     End Sub      Private _CurrentPhase As LifeCyclePhase     Private _PageListening As Page      Public ReadOnly Property CurrentPhase() As LifeCyclePhase         Get             Return _CurrentPhase         End Get     End Property      Public ReadOnly Property PageListening() As Page         Get             Return _PageListening         End Get     End Property      Private Sub AddListener()         AddHandler _PageListening.PreInit, AddressOf PreInit         AddHandler _PageListening.Init, AddressOf Init         AddHandler _PageListening.Load, AddressOf Load         AddHandler _PageListening.DataBinding, AddressOf DataBinding         AddHandler _PageListening.PreRender, AddressOf PreRender         AddHandler _PageListening.Unload, AddressOf Unload         AddHandler _PageListening.Disposed, AddressOf Disposed     End Sub      Private Sub PreInit(ByVal sender As Object, ByVal e As EventArgs)         Me._CurrentPhase = LifeCyclePhase.AfterPreInit     End Sub      Private Sub Init(ByVal sender As Object, ByVal e As EventArgs)         Me._CurrentPhase = LifeCyclePhase.AfterInit     End Sub      Private Sub Load(ByVal sender As Object, ByVal e As EventArgs)         Me._CurrentPhase = LifeCyclePhase.AfterLoad     End Sub      Private Sub DataBinding(ByVal sender As Object, ByVal e As EventArgs)         Me._CurrentPhase = LifeCyclePhase.AfterDataBinding     End Sub      Private Sub PreRender(ByVal sender As Object, ByVal e As EventArgs)         Me._CurrentPhase = LifeCyclePhase.AfterPreRender     End Sub      Private Sub Unload(ByVal sender As Object, ByVal e As EventArgs)         Me._CurrentPhase = LifeCyclePhase.AfterUnload     End Sub      Private Sub Disposed(ByVal sender As Object, ByVal e As EventArgs)         Me._CurrentPhase = LifeCyclePhase.AfterDisposed     End Sub End Class 

The handler in this class are called after the handler in the page itself, so if you f.e. check the CurrentPhase in Page.Init you'll get PreInit. Therefor i have called this phase AfterPreInit.

Partial Public Class _Default     Inherits System.Web.UI.Page     Implements ITrackingLifeCycle      Private lcl As New LifeCycleListener(Me)      Public ReadOnly Property GetLifeCycleListener() As LifeCycleListener Implements ITrackingLifeCycle.GetLifeCycleListener         Get             Return lcl         End Get     End Property 

You can now check the lifecycle-phase everywhere, even without a reference to a control via HttpContext.Current:

Public Class FooClass     Public Shared Sub Foo()         If Not (HttpContext.Current Is Nothing OrElse HttpContext.Current.Handler Is Nothing) Then             If TypeOf HttpContext.Current.CurrentHandler Is ITrackingLifeCycle Then                 Dim page As ITrackingLifeCycle = DirectCast(HttpContext.Current.CurrentHandler, ITrackingLifeCycle)                 Dim phase As LifeCyclePhase = page.GetLifeCycleListener.CurrentPhase             End If         End If     End Sub End Class 

This is neither tested sufficiently nor used by myself and certainly improvable, but maybe it helps you in your current situation.



回答2:

I think what you try to achieve is conceptually wrong because you are thinking at the page events as page state. The page can’t be at “OnInit/OnLoad/…” state just because it’s an event.

What do you need it for? maybe we could suggest you a better approach to achieve your goal.



回答3:



回答4:

As far as I understand the page lifecycle, you can't do it. Basically, Page class is the guy that has to raise events in a specific order. There is nothing in built that will tell the stage of processing. But in order to something, you can create a property and set up this property in different stages of processing.



回答5:

I found out there is actually an internal property of the Page class that does just what I am looking for: it is an enum called ControlState:

internal enum ControlState { Constructed, FrameworkInitialized, ChildrenInitialized, Initialized, ViewStateLoaded, Loaded, PreRendered } 

I believe it is possible to access internal members in C#4, see here



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!