Participating in Postbacks


Suppose that you want to display all the text boxes at your Web site with a blue background and a yellow font. It might make sense, in this situation, to simply create a custom control that renders a text box with the proper attributes. For example, the control in Listing 28.20 renders an <input> tag with a blue background and yellow foreground.

Listing 28.20 BlueTextBox.vb
 Imports System Imports System.Web Imports System.Web.UI Namespace myControls Public Class BlueTextBox Inherits Control Protected Overrides Sub Render( objTextWriter As HtmlTextWriter)   objTextWriter.AddAttribute( "Name", Me.UniqueID )   objTextWriter.AddStyleAttribute( "background-color", "Blue" )   objTextWriter.AddStyleAttribute( "color", "Yellow" )   objTextWriter.RenderBeginTag( "input" )   objTextWriter.RenderEndTag End Sub End Class End Namespace 

The C# version of this code can be found on the CD-ROM.

You can display the BlueTextBox control by using the page in Listing 28.21.

Listing 28.21 DisplayBlueTextBox.aspx
 <%@ Register TagPrefix="myControls" Namespace="myControls" Assembly="BlueTextBox"%> <html> <head><title>DisplayBlueTextBox.aspx</title></head> <body> <form Runat="Server"> <myControls:BlueTextBox   Runat="Server"/> <asp:Button   Text="Submit!"   Runat="Server" /> </form> </body> </html> 

The C# version of this code can be found on the CD-ROM.

If you post the form containing the BlueTextBox control in Listing 28.21, you run into a problem. The BlueTextBox control does not retain its value between form posts. In other words, the control does not support postbacks.

To get the BlueTextBox control to support postbacks, you need to do slightly more work. You need to implement the IPostBackDataHandler interface. This interface defines the following two methods :

  • LoadPostData ” Processes the data being posted back to the server

  • RaisePostDataChangedEvent ” Raises the change event for a control

The modified BlueTextBox control in Listing 28.22, named BlueTextBoxPostBack , illustrates how you can implement the IPostBackDataHandler interface.

Listing 28.22 BlueTextBoxPostBack.vb
[View full width]
 Imports System Imports System.Web Imports System.Web.UI Imports System.Collections.Specialized Namespace myControls Public Class BlueTextBoxPostBack Inherits Control Implements IPostBackDataHandler Public Text As String Public Function LoadPostData( PostDataKey As String, Values As NameValueCollection) As graphics/ccc.gif Boolean _ Implements IPostBackDataHandler.LoadPostData   Text =  Values( Me.UniqueID )   Return False End Function Public Sub RaisePostDataChangedEvent() _ Implements IPostBackDataHandler.RaisePostDataChangedEvent   ' Raise Change Event End Sub Protected Overrides Sub Render( objTextWriter As HtmlTextWriter )   objTextWriter.AddAttribute( "Name", Me.UniqueID )   objTextWriter.AddStyleAttribute( "background-color", "Blue" )   objTextWriter.AddStyleAttribute( "color", "Yellow" )   objTextWriter.AddAttribute( "value", Text )   objTextWriter.RenderBeginTag( "input" )   objTextWriter.RenderEndTag End Sub End Class End Namespace 

The C# version of this code can be found on the CD-ROM.

You add one new function and one new subroutine in Listing 28.22. The LoadPostData function has two parameters. The first parameter, PostDataKey , represents the unique ID for the control. The second parameter, Values , represents the values of all the form elements being posted back to the server.

NOTE

In Listing 28.22, the first parameter passed to the LoadPostData function is an instance of the NameValueCollection collection. At the top of Listing 28.22, you import System.Collections.Specialized so that you have access to this collection.


Within the LoadPostData function, you grab the value from the Values collection for the current control and assign it to the string variable named Text . Next, you return the value False from the function.

The RaisePostBackDataChanged subroutine is called only when the LoadPostData function returns the value True . In Listing 28.22, you don't do anything with this subroutine. I'll explain its purpose in a moment.

Within the Render method, you add an additional attribute, named Value , to the text box by using the AddAttribute method. You assign the value of the Text property to this attribute.

The page in Listing 28.23 illustrates how you can display the new and improved BlueTextBox control.

Listing 28.23 DisplayBlueTextBoxPostBack.aspx
 <%@ Register TagPrefix="myControls" Namespace="myControls" Assembly="BlueTextBoxPostBack"%> <html> <head><title>DisplayBlueTextBoxPostBack.aspx</title></head> <body> <form Runat="Server"> <myControls:BlueTextBoxPostBack   Runat="Server"/> <asp:Button   Text="Submit!"   Runat="Server" /> </form> </body> </html> 

The C# version of this code can be found on the CD-ROM.

If you enter data in the text box in Listing 28.23 and submit the form, the text box redisplays the data when the form is reloaded.

Remember that the BlueTextBox control had an additional subroutine, named RaisePostDataChangedEvent , which you ignored earlier. You can use this subroutine to raise a change event whenever the data in the text box changes. The control in Listing 28.24 illustrates how to do so.

Listing 28.24 BlueTextBoxChanged.vb
[View full width]
 Imports System Imports System.Web Imports System.Web.UI Imports System.Collections.Specialized Namespace myControls Public Class BlueTextBoxChanged Inherits Control Implements IPostBackDataHandler Public Event TextChanged( s As Object, e As EventArgs ) Public Property Text As String Set   ViewState( "Text" ) = Value End Set Get   If ViewState( "Text" ) <> Nothing Then     Return ViewState( "Text" )   Else     Return String.Empty   End If End Get End Property Public Function LoadPostData( PostDataKey As String, Values As NameValueCollection ) As graphics/ccc.gif Boolean _ Implements IPostBackDataHandler.LoadPostData   Dim strNewValue As String   strNewValue = Values( Me.UniqueID )   If strNewValue <> Text Then     Text = strNewValue     Return True   Else     Return False   End If End Function Public Sub RaisePostDataChangedEvent() _ Implements IPostBackDataHandler.RaisePostDataChangedEvent   OnTextChanged( EventArgs.Empty ) End Sub Protected Sub OnTextChanged( e As EventArgs )   RaiseEvent TextChanged( Me, e ) End Sub Protected Overrides Sub Render( objTextWriter As HtmlTextWriter )   objTextWriter.AddAttribute( "Name", Me.UniqueID )   objTextWriter.AddStyleAttribute( "background-color", "Blue" )   objTextWriter.AddStyleAttribute( "color", "Yellow" )   objTextWriter.AddAttribute( "value", Text )   objTextWriter.RenderBeginTag( "input" )   objTextWriter.RenderEndTag End Sub End Class End Namespace 

The C# version of this code can be found on the CD-ROM.

In Listing 28.24, you modify both the LoadPostData function and RaisePostDataChangedEvent subroutine. The LoadPostData function will now return True when the contents of the text box are changed. The new value entered into the text box is compared against a value saved in the control's view state.

If the LoadPostData function returns True , the RaisePostDataChangedEvent subroutine executes. This subroutine calls the OnTextChanged subroutine, which, in turn , raises the TextChanged event.

The ASP.NET page in Listing 28.25 illustrates how you can handle the OnTextChanged event.

Listing 28.25 DisplayBlueTextBoxChanged.aspx
 <%@ Register TagPrefix="myControls" Namespace="myControls" Assembly="BlueTextBoxChanged"%> <Script Runat="Server"> Sub BlueTextBoxChanged_TextChanged( s As Object, e As EventArgs )   lblMessage.Text = "Text Changed!" End Sub </Script> <html> <head><title>DisplayBlueTextBoxChanged.aspx</title></head> <body> <form Runat="Server"> <myControls:BlueTextBoxChanged   OnTextChanged="BlueTextBoxChanged_TextChanged"   Runat="Server"/> <asp:Button   Text="Submit!"   Runat="Server" /> <p> <asp:Label   ID="lblMessage"   ForeColor="Red"   Font-Bold="True"   EnableViewState="False"   Runat="Server" /> </form> </body> </html> 

The C# version of this code can be found on the CD-ROM.

When the BlueTextBoxChanged control is declared in Listing 28.25, the BlueTextBoxChanged_TextChanged subroutine is associated with the TextChanged event. If you submit the form containing the control and the contents of the control have been modified, the TextChanged event triggers the BlueTextBoxChanged_TextChanged subroutine.

Handling Postback Events

One last topic not yet examined concerns postbacks. In the preceding section, you learned how to repopulate a text box after a form is submitted. However, I have not discussed a method for actually posting the data from a form.

You can use three standard ASP.NET controls to post a form: Button , ImageButton , and LinkButton . All three controls generate client-side JavaScript that is executed when you submit a form. In this section, you learn how to create your own form element that generates the necessary JavaScript to raise a postback event.

To handle postback events from a custom control, you must implement the IPostBackEvent interface. This interface contains a definition for a single method: the RaisePostBack event. The control in Listing 28.26 illustrates how you can implement this method in a custom control.

Listing 28.26 TextBoxColor.vb
[View full width]
 Imports System Imports System.Web Imports System.Web.UI Imports System.Collections.Specialized Namespace myControls Public Class TextBoxColor Inherits Control Implements IPostBackDataHandler Implements IPostBackEventHandler Public BoxColor As String = "Blue" Public Text As String Public Sub RaisePostBackEvent(EventArgument As String) _ Implements IPostBackEventHandler.RaisePostBackEvent   If (eventArgument = "Red" )     Me.BoxColor = "Red"   Else     Me.BoxColor = "Blue"   End If End Sub Public Function LoadPostData(PostDataKey As String, Values As NameValueCollection) As graphics/ccc.gif Boolean _ Implements IPostBackDataHandler.LoadPostData   Dim strNewValue As String   Text = Values( Me.UniqueID )   Return False End Function Public Sub RaisePostDataChangedEvent() _ Implements IPostBackDataHandler.RaisePostDataChangedEvent   ' Raise Change Event End Sub Protected Overrides Sub Render( objTextWriter As HtmlTextWriter )   objTextWriter.AddAttribute( "Name", Me.UniqueID )   objTextWriter.AddStyleAttribute( "background-color", BoxColor )   objTextWriter.AddStyleAttribute( "color", "Yellow" )   objTextWriter.AddAttribute( "value", Text )   objTextWriter.RenderBeginTag( "input" )   objTextWriter.RenderEndTag   objTextWriter.WriteLine( "<p>" )   objTextWriter.AddAttribute( "Type", "Button" )   objTextWriter.AddAttribute( "Value", "Display Red!" )   objTextWriter.AddAttribute( "OnClick", "JScript:" & Page.GetPostBackEventReference( Me, graphics/ccc.gif "Red" ) )   objTextWriter.RenderBeginTag( "Input" )   objTextWriter.RenderEndTag()   objTextWriter.WriteLine( "&nbsp;&nbsp;" )   objTextWriter.AddAttribute( "Type", "Button" )   objTextWriter.AddAttribute( "Value", "Display Blue!" )   objTextWriter.AddAttribute( "OnClick", "JScript:" & Page.GetPostBackEventReference( Me, graphics/ccc.gif "Blue" ) )   objTextWriter.RenderBeginTag( "Input" )   objTextWriter.RenderEndTag() End Sub End Class End Namespace 

The C# version of this code can be found on the CD-ROM.

The control in Listing 28.26 displays a text box and two buttons . When you click the button labeled Display Red! , the background color of the text box changes to red. When you click the button labeled Display Blue! , the background color changes to blue.

Both buttons are rendered within the control's Render method. They are created with an OnClick attribute that has a JScript function as its value. For example, the OnClick attribute for the Display Red! button is declared like this:

 
[View full width]
 
[View full width]
objTextWriter.AddAttribute( "OnClick", "JScript:" & Page.GetPostBackEventReference( Me, graphics/ccc.gif "Red" ) )

The GetPostBackEventReference method returns a reference to the JavaScript function on the client; this reference causes the form to be posted back to the server. The first parameter passed to the method represents the control that will process the postback event on the server. In this case, you use the Visual Basic keyword Me , which refers to the current control.

The second parameter is optional. It's an argument passed back to the server during postback. In this case, you pass back the argument "Red" so that you can detect that the Display Red! button was clicked.

When the Display Red! button is rendered, the following code is sent to the browser:

 
 <input Type="Button" Value="Display Red!" OnClick="JScript:__doPostBack ('ctrl4','Red') " /> 

The Display Red! button triggers the client-side JavaScript function named __doPostBack . Notice that the unique ID of the control and parameter are passed by the function.

You can view the source of the __doPostBack function by selecting View Source on your browser. In case you're curious , the __doPostBack function looks like this:

 
 function __doPostBack(eventTarget, eventArgument) {     var theform = document.ctrl1     theform.__EVENTTARGET.value = eventTarget     theform.__EVENTARGUMENT.value = eventArgument     theform.submit() } 

The __doPostBack function initializes two arguments and submits the form back to the server.

When the form is posted back to the server, the custom control's RaisePostBack method is executed. This method looks like this:

 
 Public Sub RaisePostBackEvent(EventArgument As String) _ Implements IPostBackEventHandler.RaisePostBackEvent   If (eventArgument = "Red" )     Me.BoxColor = "Red"   Else     Me.BoxColor = "Blue"   End If End Sub 

This method detects whether Display Red! or Display Blue! was clicked. If the Display Red! button was clicked, the BoxColor property is assigned the value Red . Otherwise, the property is assigned the value Blue .

When the control renders the text box in the control's Render method, it uses the value of the BoxColor property when setting the background color of the text box.

You can test the TextBoxColor control by using the ASP.NET page in Listing 28.27.

Listing 28.27 DisplayTextBoxColor.aspx
 <%@ Register TagPrefix="myControls" Namespace="myControls" Assembly="TextBoxColor"%> <html> <head><title>DisplayTextBoxColor.aspx</title></head> <body> <form Runat="Server"> <myControls:TextBoxColor   Runat="Server"/> </form> </body> </html> 

The C# version of this code can be found on the CD-ROM.



ASP.NET Unleashed
ASP.NET 4 Unleashed
ISBN: 0672331128
EAN: 2147483647
Year: 2003
Pages: 263

Similar book on Amazon

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net