FREE BOOK

Chapter 5: Event-Based Programming

Posted by Apress Free Book | ASP.NET January 02, 2009
In this chapter, we explore the intricacies of working with server control events.

Init Event
 
The first phase processed by the control is the Init event. We are notified of this phase by overriding the protected OnInit method inherited from the base class
 
 using System.Web.UI.Control;   
 
override protected void OnInit(System.EventArgs e)
     {
         base.OnInit();
         Trace("Lifecycle: Init Event.");
     }
 

The code in the OnInit method uses a private utility method called Trace thatcsends status information to the Trace class via the control's Context property availablecto ASP.NET server controls:
 
     private void Trace(string info)
     {
         Page.Trace.Warn(info);
         Debug.WriteLine(info);
     }

 
This class method also sends output to the debug stream via the System.Diagnostics.Debug class and its WriteLine method. The reason for this extra step is to view Unload and Dispose event execution, which occurs after the Web Form is finished writing out its content via the Render method and the ASP.NET trace tables have been generated. You can view debug stream information in the Output window of Visual Studio .NET when debugging.
 
The Init event is an opportunity for the control to initialize any resources it needs to service the page request. A control can access any child controls in this method if necessary; however, peer- and parent-level controls are not guaranteed to be accessible at this point in the life cycle.
 
Overriding methods such as OnInit from the base class System.Web.UI.Control requires that we call the base version of this method to ensure proper functioning of the event. The base class implementation of OnInit actually raises the Init event exposed by the root Control class to clients. If you override OnInit but do not call the base class version of this event, the event will not be raised to clients that are registered to receive it. This applies to the other On-prefixed methods such as OnLoad, OnPreRender, and OnUnload, which are part of the life cycle process, as well as other non-life-cycle-specific event methods such as OnDataBinding and OnBubbleEvent.
 
TrackViewState Method
 
The TrackViewState method executes immediately after initialization and marks the beginning of ViewState processing, and state tracking, in the control life cycle. If you have attribute values that you do not want to save in ViewState across page round-trips for efficiency purposes, you should set these values in the OnInit method. Otherwise, all control property value modifications performed after this method executes will persist to ViewState.
 
If desired, you can make modifications to state values in this method that won't be marked as dirty as long as you do so before executing the inherited base.TrackViewState method or before calling the encapsulated StateBag.TrackViewState method.
 
Load Event
 
The Load event should be quite familiar to you because we have leveraged this convenient location for common page code in our Web Forms in previous examples. It is a handy place to put page initialization logic because you are guaranteed that all controls in the Page's control tree are created and all state-loading mechanisms have restored each control's state back to where it was at the end of the previous request/ response page round-trip. This event also occurs before any controls in the Page's control tree fire their specific events resulting from value changes in postback data. To customize control behavior in this phase, override the OnLoad method.
 
PreRender Event
 
The PreRender event is a phase in the control life cycle that represents the last-ditch chance for a control to do something before it is rendered. This is the location to put code that must execute before rendering but after the Load event, state management methods, and postback events have occurred. Controls can override the OnPreRender method for this special situation. Note that changes made to a control's state at this point in the life cycle will persist to ViewState.
 
SaveViewState Method
 
The SaveViewState method saves the ViewState dictionary by default without any additional action by you. Overriding this method is only necessary when a control needs to customize state persistence in ViewState. This method is called only when the EnableViewState property inherited from Control is set to true. The object instance that is returned from this method is serialized by ASP.NET into the final ViewState string that is emitted into the page's _VIEWSTATE hidden field. Be aware that SaveViewState is called twice in our sample code as a result of enabling page tracing, which makes a call to SaveViewState to gather information for tracing purposes. With tracing disabled during normal page execution, SaveViewState is called only once.
 
Render Method

You are by now very familiar with overriding the Render method in a custom control to generate a control's UI. The HtmlTextWriter class does the bulk of the work here, writing out the control as HTML and script where applicable to the HTTP response stream. Note that any changes to a control's state made within this method will render into the UI but will not be saved as part of ViewState.
 
Unload Event
 
The Page class implements this method to perform cleanup. Overriding the OnUnload method from the base control class allows the control to hook into this event. Although the Unload event is an opportunity for a control to release any resources that it has obtained in earlier control events such as Init or Load, it is recommended that you release resources in its Dispose method.
 
The trace output from the ASP.NET page does not display any information pertaining to this event because it fires after Render executes, but we can use the debug stream output from the Output window when debugging the Web Form in Visual Studio .NET to see the result:
 
 Lifecycle: Init Event.
 Lifecycle: Track ViewState.
 Lifecycle: Load Event.
 Lifecycle: PreRender Event.
 Lifecycle: Save ViewState.
 Lifecycle: Save ViewState.
 Lifecycle: Render Event.
 Lifecycle: Unload Event.
 Lifecycle: Dispose Event.
 
Dispose Method
 
Dispose is the recommended location for cleaning up resources. Implementing a Dispose method is recommended in .NET Framework programming when unmanaged resources (such as a connection to SQL Server) are acquired by a control and need to be safely released within the garbage collection architecture. The pattern is based on the IDispose interface that gives a way for clients to tell an object to clean up its unmanaged resources:
 
 Interface IDispose
 {
 
    void Dispose();
 }

 
Once a client is finished working with an object, the client notifies the object it is finished by calling the object's Dispose method. This gives the object immediate confirmation that it can clean up its resources instead of waiting for its Finalize method to be called during garbage collection. Because Dispose is the design pattern common in .NET, it is recommended that you implement cleanup in Dispose instead of Unload to release unmanaged resources.
 
HTTP POST Request via Postback
 

Additional events and methods of the control life cycle are exercised once we execute a postback of the Life Cycle Web Form by clicking the button. The output of the trace is much larger, so the screen shot in Figure 5-24 is filled by that table.
 
 
 
 Figure 5-24. The Lifecycle.aspx Trace output from an HTTP POST postback

The output from the Visual Studio .NET Debug window confirms the sequence of events as well:
 
 Lifecycle: Init Event.
 Lifecycle: Track ViewState.
 Lifecycle: Load PostBack Data Event.
 Lifecycle: Load Event.
 Lifecycle: Post Data Changed Event.
 Lifecycle: PostBack Event.
 Lifecycle: PreRender Event.
 Lifecycle: Save ViewState.
 Lifecycle: Save ViewState.
 Lifecycle: Render Event.
 Lifecycle: Unload Event.
 Lifecycle: Dispose Event.
 LoadViewState Method
 
Overriding the LoadViewState method is necessary if a control has previously overridden SaveViewState to customize ViewState serialization. Customization of the View- State persistence mechanism is commonly performed by developers in more complex controls that have complex properties such as a reference type or a collection of objects. The decision to customize ViewState really comes down to whether or not a control's state can be easily or efficiently reduced to a string representation.
 
LoadPostBackData Method
 
In the previous chapter, we discussed how to retrieve client form post data via implementation of the IPostBackDataHandler interface. The LoadPostData routine is given the opportunity to process the postback data and to update the control's state. It also allows the control to notify ASP.NET that it wishes to raise an event at a later time in order to permit clients a chance to process the state change. For our purposes, the Lifecycle control always returns true, so the change event is always raised. Keen observers will notice that we really should not be receiving the form post information, because we did not emit an HTML tag such as <INPUT>. However, we greased the wheels in the ASP.NET framework by calling Page.RegisterRequiresPostBack in OnPreRender:
 
     override protected void OnPreRender(System.EventArgs e)
     {
         base.OnPreRender(e);
         Trace("Lifecycle: PreRender Event.");
         Page.RegisterRequiresPostBack(this);
     }
 

This makes it possible to receive a call to our LoadPostData method by ASP.NET. We perform a similar task in LoadPostData to ensure we receive the PostBack event by calling Page.RegisterRequiresRaiseEvent:
 
     public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
     {
         Trace("Lifecycle: Load PostBack Data Event.");
         Page.RegisterRequiresRaiseEvent(this);
         return true;
     }

 
 RaisePostDataChangedEvent Method
 
For controls that have state changes reflected in postback data, these controls most likely need to raise server-side events. These events are raised from within the RaisePostDataChangedEvent method of each respective control. Following this design guideline ensures that control state is restored from ViewState and updated from postback data before the various events begin to fire. Raising server-side events from within any other control method can cause hard-to-debug side effects for event consumers. This routine is called only if the LoadPostData returns true.
 
RaisePostBackEvent Method
 
Implementing RaisePostBackEvent ensures that the server control notifies ASP.NET that the state of the control has changed. To participate in postback processing, a control must implement the IPostBackEventHandler interface. Controls implement this interface and emit some sort of HTML to submit the Web Form back to the server, whether via a button or an HTML element with JavaScript code to submit the form programmatically.
 
In our sample Lifecycle control, we rigged the system by calling Page.RegisterRequiresRaiseEvent in the LoadPostData method. Our SuperButton control sample in this chapter demonstrates how to execute this properly. We use this shortcut to hook into this event for purposes discussing the control life cycle.

Total Pages : 12 89101112

comments