Wrox Home  
Search P2P Archive for: Go

  Return to Index  

aspx_mobile thread: Creating a TimerForm Mobile Control


Message #1 by "Goh Mingkun" <mangokun@h...> on Sun, 31 Mar 2002 00:50:14
Creating a TimerForm Mobile Control
[Code mostly taken from Microsoft Mobile Internet Toolkit QuickStart 
Tutorial]
(Tested with Microsoft Visual Studio .net Enterprise Architect, Microsoft 
Internet Explorer 6.0, Nokia Mobile Internet Toolkit v3.0's WAP June 2000 
Simulator)

The base set of controls offered by the Microsoft Mobile Internet Toolkit 
does not include a TimerForm control. This control can be used to cause a 
mobile browser to post back to the server or navigate to another link 
after a specified time period. 

Here I show you how to create such a control, which will let you use it in 
any Mobile Web Application. This control also includes custom adapters 
that emit browser-specific markup, and are instantiated based on the type 
of browser being targeted. 

The TimerForm control inherits from the Form control, and provides 
properties to specify a time-out period, the name of a server-side method 
to invoke after the time-out, and a URL to navigate to after the time-out 
(only one of these last two properties is used). 

Note: For HTML-based devices, the TimerForm control emits a refresh META 
tag into the HTML response. These tags are unsupported on J-Phone and NTT 
Docomo devices. Therefore, the TimerForm control does not invoke postback 
and does not work on such devices. 


__________________________________________________

Step to create the TimerForm Mobile Control (you only need to do it once):

1. Create a "Web Control Library" project called 'TimerFormVB'.

2. Delete 'WebCustomControl1.vb' from this project

3. "Add Reference" to this project.
   In the .NET Tab, select the Component "System.Web.Mobile.dll", and make 
sure you add it to the list below, and then click on OK.

4. "Add New Item" to this project.
   Choose "WebCustomControl" from the Templates list.
   Name it 'TimerForm.vb'.
   Click on Open.

5. Paste everything below into 'TimerForm.vb', replacing everything in it

- Code begins after this line -
Imports System.ComponentModel
Imports System.Web.UI
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Imports System.Web.UI.MobileControls
Imports System.Web.UI.MobileControls.Adapters

' ====================================================================
'
' TimerForm Control Class
'
' The TimerForm control inherits from Form, and adds the ability
' to make the browser navigate to a URL or post back to the server
' after a specified time.
'
' To set the specified delay, set the Delay property.
'
' To make the browser navigate to a URL, set the AutoNavigateUrl
' property.
'
' To make the browser post back, leave AutoNavigateUrl blank. To
' handle the resulting event, set an event handler for the Timer
' event, or override OnTimer in an inheriting class.
'
' ====================================================================

<DefaultProperty("Text"), ToolboxData("<{0}:TimerForm runat=server></
{0}:TimerForm>")> _
Public Class TimerForm : Inherits System.Web.UI.MobileControls.Form

    ' ================================================================
    '
    ' Delay property
    '
    ' Defines, in seconds, how long to delay before executing action.
    ' Defaults to ten seconds.
    '
    ' ================================================================

    Public Property Delay() As Integer

        Get
            Dim o As Object = ViewState("Delay")
            If o Is Nothing Then
                Return 10
            Else
                Return CType(o, Integer)
            End If
        End Get

        Set(ByVal Value As Integer)
            ViewState("Delay") = Value
        End Set

    End Property

    ' ================================================================
    '
    ' AutoNavigateUrl property 
    '
    ' If defined, renders markup to make the browser automatically 
    ' navigate to the given URL after the specified time.
    '
    ' ================================================================

    Public Property AutoNavigateUrl() As String

        Get
            Dim o As Object = ViewState("AutoNavigateUrl")
            If o Is Nothing Then
                Return String.Empty
            Else
                Return CType(o, String)
            End If
        End Get

        Set(ByVal Value As String)
            ViewState("AutoNavigateUrl") = Value
        End Set

    End Property

    ' ================================================================
    '
    ' Timer event
    '
    ' This event is raised when the timer elapses, and the browser
    ' posts back to the server. If AutoNavigateUrl is defined, no
    ' postback happens.
    '
    ' ================================================================

    Public Event Timer(ByVal sender As Object, ByVal e As EventArgs)

    ' ================================================================
    '
    ' OnTimer method
    '
    ' This protected method allows inheriting classes to internally 
    ' handle a post back following the specified delay. The default
    ' implementation raises the Timer event.
    '
    ' ================================================================

    Protected Overridable Sub OnTimer(ByVal e As EventArgs)

        RaiseEvent Timer(Me, e)

    End Sub

    ' ================================================================
    '
    ' RaiseTimer method
    '
    ' Called by the adapters to raise the timer event.
    '
    ' ================================================================

    Public Sub RaiseTimer()

        OnTimer(New EventArgs())

    End Sub

End Class

' ====================================================================
'
' WmlTimerFormAdapter Class
'
' The WmlTimerFormAdapter class renders a TimerForm control on
' WML devices. The timer functionality is rendered using an
' <onevent type="timer"> construct. All other behavior
' is inherited from WmlFormAdapter.
'
' ====================================================================

Public Class WmlTimerFormAdapterVB : Inherits WmlFormAdapter

    Private Const TimerEventArgument As String = "$timer"

    Protected Shadows ReadOnly Property Control() As TimerForm

        Get
            Return CType(MyBase.Control, TimerForm)
        End Get

    End Property

    ' ================================================================
    '
    ' RenderExtraCardElements method
    '
    ' By overriding this method, the adapter can render additional
    ' content immediately after the <card> tag in the WML output.
    '
    ' ================================================================

    Protected Overrides Sub RenderExtraCardElements(ByVal writer As 
WmlMobileTextWriter)

        Dim autoNavigateUrl As String = Control.AutoNavigateUrl

        ' A URL to another form on the same page will also cause a 
postback.

        Dim renderAsPostBack As Boolean = False
        If autoNavigateUrl.Length = 0 Then
            renderAsPostBack = True
        ElseIf Not (DeterminePostBack(autoNavigateUrl) Is Nothing) Then
            renderAsPostBack = True
        End If

        writer.WriteBeginTag("onevent")
        writer.WriteAttribute("type", "ontimer")
        writer.Write(">")

        If (renderAsPostBack) Then

            writer.RenderGoAction(Control.UniqueID, TimerEventArgument, 
WmlPostFieldType.Normal, False)

        Else

            ' Resolve the URL relative to the page.
            autoNavigateUrl = Control.ResolveUrl(autoNavigateUrl)

            writer.WriteBeginTag("go")
            writer.Write(" href=")
            writer.Write(Chr(34))
            writer.WriteEncodedUrl(autoNavigateUrl)
            writer.Write(Chr(34))
            writer.Write(">")

        End If

        writer.WriteEndTag("onevent")
        writer.WriteLine()

        writer.WriteBeginTag("timer")
        ' WML timer lengths are in 10th of seconds.
        writer.WriteAttribute("value", (Control.Delay * 10).ToString())
        writer.WriteLine("/>")

    End Sub

    ' ================================================================
    '
    ' HandlePostBackEvent method
    '
    ' By overriding this method, the adapter can handle the postback
    ' generated from the timer.
    '
    ' ================================================================

    Public Overrides Function HandlePostBackEvent(ByVal eventArgument As 
String) As Boolean

        If (eventArgument = TimerEventArgument) Then

            Dim autoNavigateUrl As String = Control.AutoNavigateUrl
            If autoNavigateUrl.Length > 0 Then

                If (autoNavigateUrl.Length > 1) And (autoNavigateUrl.Chars
(0) = "#") Then
                    Page.ActiveForm = Control.ResolveFormReference
(autoNavigateUrl.Substring(1))
                End If

            Else

                Control.RaiseTimer()

            End If

            HandlePostBackEvent = True
        Else

            ' Let the base adapter class handle any events.

            HandlePostBackEvent = MyBase.HandlePostBackEvent(eventArgument)

        End If

    End Function

End Class

' ====================================================================
'
' HtmlTimerFormHelper Class
'
' The HtmlTimerFormHelper class is a helper class used by both
' HtmlTimerFormAdapter and ChtmlTimerFormAdapter. Although both
' these classes require identical functionality, they have different
' base classes, making a helper class useful.
'
' On HTML devices, the timer functionality is rendered using a
' <meta http-equiv="refresh"> construct. All other behavior
' is inherited from the base form adapter.
'
' ====================================================================

Class HtmlTimerFormHelperVB

    Private Const TimerEventArgument As String = "$timer"

    ' ================================================================
    '
    ' RenderTimerMetaTag method
    '
    ' Renders the metatag for the timer behavior.
    '
    ' ================================================================

    Public Shared Sub RenderTimerMetaTag(ByVal form As TimerForm, ByVal 
writer As HtmlMobileTextWriter)

        Dim autoNavigateUrl As String = form.AutoNavigateUrl

        ' A URL to another form on the same page will also cause a 
postback.

        Dim renderAsPostBack As Boolean = False
        If autoNavigateUrl.Length = 0 Then
            renderAsPostBack = True
        ElseIf autoNavigateUrl.Chars(0) = "#" Then
            renderAsPostBack = True
        End If

        writer.WriteBeginTag("meta")
        writer.WriteAttribute("http-equiv", "refresh")
        writer.Write(" content=")
        writer.Write(Chr(34))
        writer.Write(form.Delay.ToString())
        writer.Write(";url=")
        If renderAsPostBack Then

            Dim pageAdapter As HtmlPageAdapter = CType
(form.MobilePage.Adapter, HtmlPageAdapter)
            pageAdapter.RenderUrlPostBackEvent(writer, form.UniqueID, 
TimerEventArgument)

        Else

            writer.WriteEncodedUrl(autoNavigateUrl)

        End If
        writer.Write(Chr(34))
        writer.WriteLine(">")

    End Sub

    ' ================================================================
    '
    ' HandlePostBackEvent method
    '
    ' Handles a timer postback event.
    '
    ' ================================================================

    Public Shared Function HandlePostBackEvent(ByVal form As TimerForm, 
ByVal eventArgument As String) As Boolean

        If (eventArgument = TimerEventArgument) Then

            Dim autoNavigateUrl As String = form.AutoNavigateUrl

            If (autoNavigateUrl.Length > 0) Then

                If (autoNavigateUrl.Length > 1) And (autoNavigateUrl.Chars
(0) = "#") Then

                    form.MobilePage.ActiveForm = form.ResolveFormReference
(autoNavigateUrl.Substring(1))

                End If

            Else

                form.RaiseTimer()

            End If

            HandlePostBackEvent = True

        Else

            HandlePostBackEvent = False

        End If

    End Function

End Class

' ====================================================================
'
' HtmlTimerFormAdapter Class
'
' The HtmlTimerFormAdapter class renders a TimerForm control on
' HTML devices. The timer functionality is rendered using a
' <meta http-equiv="refresh"> construct. All other behavior
' is inherited from HtmlFormAdapter.
'
' ====================================================================

Public Class HtmlTimerFormAdapterVB : Inherits HtmlFormAdapter

    Protected Shadows ReadOnly Property Control() As TimerForm

        Get
            Return CType(MyBase.Control, TimerForm)
        End Get

    End Property

    ' ================================================================
    '
    ' RenderExtraHeadElements method
    '
    ' By overriding this method, the adapter can render additional
    ' content inside the <head> tag of the rendered page. The adapter
    ' must call the base class implementation.
    '
    ' ================================================================

    Protected Overrides Function RenderExtraHeadElements(ByVal writer As 
HtmlMobileTextWriter) As Boolean

        MyBase.RenderExtraHeadElements(writer)

        ' The method is called twice - once with the writer set to null,
        ' to determine if there is anything to be written; and once with
        ' a valid writer.

        If Not (writer Is Nothing) Then

            HtmlTimerFormHelperVB.RenderTimerMetaTag(Control, writer)

        End If

        RenderExtraHeadElements = True

    End Function

    ' ================================================================
    '
    ' HandlePostBackEvent method
    '
    ' By overriding this method, the adapter can handle the postback
    ' generated from the timer.
    '
    ' ================================================================

    Public Overrides Function HandlePostBackEvent(ByVal eventArgument As 
String) As Boolean

        If (HtmlTimerFormHelperVB.HandlePostBackEvent(Control, 
eventArgument) = True) Then

            HandlePostBackEvent = True

        Else

            ' Let the base adapter class handle any events.

            HandlePostBackEvent = MyBase.HandlePostBackEvent(eventArgument)

        End If

    End Function

End Class

' ====================================================================
'
' ChtmlTimerFormAdapter Class
'
' The ChtmlTimerFormAdapter class renders a TimerForm control on
' scriptless HTML devices. The timer functionality is rendered using 
' a <meta http-equiv="refresh"> construct. All other behavior
' is inherited from ChtmlFormAdapter.
'
' ====================================================================

Public Class ChtmlTimerFormAdapterVB : Inherits ChtmlFormAdapter
End Class
- Code ends before this line -

6. Build this project and then it is ready to be used in any Mobile Web 
Application.


__________________________________________________

In each Mobile Web Application that will be using the TimerForm Mobile 
Control, you must follow the steps below:

1. In the Web.config file of the Mobile Web Application project, add the 
lines below to specify the device adapter mappings.

<configuration>
    
  <system.web>

    <mobileControls>

        <device name="HtmlDeviceAdapters2" 
inheritsFrom="HtmlDeviceAdapters">
            <control name="TimerFormVB.TimerForm, TimerFormVB"      
                        adapter="TimerFormVB.HtmlTimerFormAdapterVB, 
TimerFormVB" />
        </device>
        
        <device name="ChtmlDeviceAdapters2" 
inheritsFrom="ChtmlDeviceAdapters">
            <control name="TimerFormVB.TimerForm, TimerFormVB"      
                        adapter="TimerFormVB.ChtmlTimerFormAdapterVB, 
TimerFormVB" />
        </device>
        
        <device name="UpWmlDeviceAdapters2" 
inheritsFrom="UpWmlDeviceAdapters">
            <control name="TimerFormVB.TimerForm, TimerFormVB"      
                        adapter="TimerFormVB.WmlTimerFormAdapterVB, 
TimerFormVB" />
        </device>
        
        <device name="WmlDeviceAdapters2" inheritsFrom="WmlDeviceAdapters">
            <control name="TimerFormVB.TimerForm, TimerFormVB"      
                        adapter="TimerFormVB.WmlTimerFormAdapterVB, 
TimerFormVB" />
        </device>

    </mobileControls>
  
  </system.web>

</configuration>

2. In your Toolbox, select the "Mobile Web Forms" Tab (or any Tab you 
like).
   Right-click anywhere in this Tab and click "Customize Toolbox...".
   In the .NET Framework Components Tab, click on Browse... and change to 
the bin directory of your TimerFormVB Web Control Library project.
Select the assembly 'TimerFormVB.dll' and click on Open.
You should notice that a new Control (named TimerForm) has been added to 
the bottom of the Toolbox Tab.
(Skip this step if you already have the TimerForm Control in the Toolbox 
Tab)
(Optional: You can customize the icon shown beside this Toolbox Control, 
go to the bottom of this Tutorial to know how.)

3. Now you can drag and drop as many TimerForm Controls onto your Mobile 
Web Forms, just like the Form Control.
   You can then change the Delay property, AutoNavigateUrl property for 
any of them.


__________________________________________________

For more info on this subject, look under the Documentation for device 
specific->adapters or adapters->device specific rendering.

mangokun@h..., 31 March, 2002
Before I wrote all this down, I worked(alone) on this TimerForm stuff for 
almost 2 days, but was very happy when I finally got it to work.

__________________________________________________

Customize Toolbox Icons

You can create your own custom bitmap to give your UserControl or 
component its own unique toolbox icon. Simply add a 16-by-16 bitmap to 
your project and give it the same name as the component for example, 
MyComponent.bmp. Set its Build action to Embedded Resource.

by Bill McCarthy, Barongarook, Victoria, Australia
Taken from 
http://www.fawcette.com/vsm/2002_01/online/online_eprods/vsnet_bmccarthy_1_
17/

__________________________________________________

Keywords:
Mobile Web Forms
Web Custom Control
TimerForm Mobile Control
VB

  Return to Index