HomeDigital EditionSearch Dotnet Cd
ASP.NET C# Certification Exams The CLI Data Access Editorials Extending .NET Fundamentals Interoperability Interviews Migrate Mobile .NET Mono .NET Interface Object-Oriented Programming Open Source Optimization Product/Book Reviews Security Source Code UML Visual Studio .NET

The Mobile Internet Toolkit comes prepackaged with a variety of controls that address the most common mobile computing tasks. However, specialized tasks can arise that these generic controls are not powerful enough to address, or for which they simply fail to meet the requirements. In these cases it is beneficial to develop a custom control that is suited to fulfilling the required tasks.

In this article, I will concentrate on developing and implementing such custom controls within a mobile application. The primary focus will not be on creating custom user controls and/or inherited controls since these can be created for the Mobile Internet Toolkit in much the same way as a standard ASP.NET control. Rather, I will focus on creating custom controls from scratch so I can address some of the unique issues of mobile Internet development. Before I begin, it is essential that you understand exactly how a mobile Web control operates.

How ASP.NET Mobile Controls Function
ASP.NET controls are in a sense a hybrid of traditional Windows form controls and HTML controls. Standard HTML controls are able to furnish a graphical interface component that can be loaded into a browser window via an HTTP protocol, but they require that all forms of state management be handled manually. ASP.NET controls overcome this limitation by moving the graphical component of HTML controls to a server-based component that manages properties and states. This means that each time the client calls the control, the fields are not reinitialized to their default value. Rather, the values stored in these fields from the previous instance of the control are maintained. This basic architecture is shared by mobile ASP.NET controls, with one big difference. The ASP.NET control architecture is centered around delivering HTML to browser clients. This type of layout is not suitable for extending functionality to the diversity of mobile devices that the Mobile Internet Toolkit targets. For instance, HTML might be acceptable for a Pocket PC running Microsoft's Pocket Internet Explorer, but it would do little to facilitate display on a WML-enabled phone.

For this reason, mobile controls place calls to device-specific adapter classes, which in turn output the appropriate markup for the type of browser detected by the Mobile Internet Toolkit runtime. Client requests are routed to an instance of a control class to handle all device-independent logic and one instance of a device adapter class to handle device-specific rendering and any other desired device-specific functionality (see Figure 1). If you are coding inherited controls you do not always need to create device-specific adapters, since the adapter functionality inherited from the parent control is often adequate. However, in order to make any custom control that you write (i.e., from scratch) compatible with the wealth of devices supported by the Mobile Internet Toolkit, you will need to code at least two types of device-specific adapters ­ an HTML adapter class and a WML adapter class. Other device adapters can also be coded to implement cHTML or other types of markups.

Figure 1

In order to get a better feel for how these device adapters function, I will develop a simple custom control and its required device adapters and develop a specialized label. Of course, more exquisite functionality is possible (e.g., custom events, methods, etc.), but these techniques are beyond the scope of the article, and are common to the development of almost all types of controls under the .NET Framework. The control I develop here will be a specialized label that might be used by doctors to check on their patients from anywhere in the hospital by accessing a mobile Web page that will display patient information on their mobile device. This control will display the patient's name, room number, and status.

To start a mobile Internet controls project, you create a Web Control Library project, just as you would to start an ASP.NET controls project, and then add a reference to System.Web.Mobile.dll, which provides access to classes in the System.Web.UI.MobileControls namespace. The Web Control Library wizard will create a default class, WebCustomControl1, which inherits from System.Web.UI.WebControls.WebControl. When you create a mobile control, you need to change the base class to MobileControl. Since mobile controls use device-adapter classes to handle client rendering, you can also delete the Render method provided by the wizard.

After making those changes I begin to lay out the device-independent logic of the control, which in this case amounts to the code that will create three properties: the patient's name, room number, and status. I will call these properties Pname, Room, and Status, respectively. After defining these properties my code looks like Listing 1.

It's not always necessary to create controls from scratch like I did here. If your desired control parallels the functionality of an existing control closely enough, like a numeric text box versus a normal text box, inheritance may actually be a better option. If I had been developing an inherited control I would have inherited from a preexisting class like TextBox that defines the control of interest. The remainder of the code lays out the three string properties that the control will utilize.

Since I'm building a custom control I now have another task: developing the device-specific adapter classes. If I were inheriting from another control I probably wouldn't need to do this. In many cases the device adapters that are made available through the inheritance of the parent control are sufficient.

Now that I have my label control I'd like to be able to render it to HTML, just like I would in ASP.NET. To do this for mobile controls I create a class I'll call CLHTMLAdapter that inherits from the HTMLControl Adapter class in the System.Web.UI.MobileControl.Adapter namespace. HTMLControlAdapter contains useful functionality for sending HTML to the client.

The next step is crucial in the development of device adapters ­ all device adapters must have a strongly typed property called Control. This will return an object that is typed to the control class that will work with this adapter. The .NET Framework uses this property to associate device adapter classes with the appropriate control class.

Finally, I need to write a Render method on my adapter class. Since I chose to inherit from HtmlControlAdapter I need to override its Render function, which takes an HtmlMobileTextWriter as an argument. Different Adapter classes define their Render methods slightly differently, but they all take an instance of a MobileTextWriter-derived class. I've summarized the most commonly used methods in this class in Table 1. For my control I will write out the patient's name, room number, and status, as shown in Listing 2.

Table 1

Now that my HTML adapter is done, my control will be visible from browsers but not from cell phones, pagers, or other WML devices. To enable access from these devices, I create a second device-adapter class, derived from WmlControlAdapter, as shown in Listing 3.

As you can see, the WML device adapter is structured in much the same way as the HTML device adapter. This time my Render method uses the passed WmlMobileTextWriter to create WML-based markup to send to the client. It is important to note that after calls to EnterStyle or EnterLayout the RenderText method must be employed rather than a Write method, since the Enter methods of the WMLMobileTextWriter are unable to render tags. Instead they just indicate in what format tags should be output upon rendering. WML does not offer the same range of possibilities as HTML, something you should take into account in your display design.

Now that I've authored my control and some Adapter classes, I compile them into an assembly together. Controls and adapters don't necessarily need to be compiled into the same assembly, but for simplicity I just compiled them into an assembly named CustomLabel.

Now I'm ready to use my custom control in a mobile Web application. I start by using the Mobile Web Application Project wizard and adding a reference to CustomLabel.dll. Next I edit my WebForm.aspx file by right-clicking on the file in Solution Explorer and selecting Open With, followed by Text Editor. Then I need to add a reference to the control library to the WebForm, as well as embed the control into the page body. I do this by adding these lines, part of Listing 4.

<%@ Register TagPrefix="CustomLabel" Namespace="CustomLabel"
Assembly="CustomLabel" %>
.....
<CustomLabel:CLabel id="CLabel1" runat="server" Status="Stable"
Room="23" Pname="John Doe"></CustomLabel:CLabel>

The <%@ Register %> directive defines the name of the tag that will represent the control in the ASP.NET page, while the other line of code defines the default state for the control. In order to refer to control in the code behind the form (.aspx.cs), you should add a using statement that points to the control's namespace.

At this point I am almost finished. The last thing to do is to configure the application to use the new device adapters so that the label will render properly on different types of clients. ASP.NET uses Web.config to do this by editing the Web.config file of the application, which is an XML-based file that stores application and server settings. As a starting point, find the machine.config file located in Windows/Microsoft .NET/Framework/version/CONFIG and open it in a text editor. Find the section that runs from <mobileControls> to </mobileControls> and copy it into the application Web.config file in place of the default line <mobile- Controls cookielessDataDictionaryType="System.Web.Mobile.CookielessData" />. This section of the .config file specifies which mobile controls work with which device adapters. By adding this to the project's Web.config file I can override the server defaults stored in machine.config and enable the application to work with my custom device adapters. I will now need to make the changes and additions highlighted in Listing 5.

You will notice that the highlighted changes all occur within the <device> ... </device> sections, which define each adapter set. It is important that each adapter set have a unique name so that the compiler does not confuse the customized sets with the default sets. Notice that within the HTML adapter set and the WML adapter set I define the particular adapter required by the control, using the syntax <control name ="control name, assembly name" adapter="adapter name, assembly name" />. This defines which device adapters are called for a particular client rendering of the control.

You may have also noticed that the Web.config file defines two other device adapter sets, one for cHTML and one for UpWML (used for Phone.com phones). Since I did not develop specific device adapters for these sets I define them so that they inherit functionality from my customized HTML and WML device adapter sets. In this way they will utilize the HTML and WML rendering methods defined for those sets respectively.

Now I am ready to make use of the customized control. To test it out, I add some values to each of the properties that were laid out and run the application. Figure 2 demonstrates how it should render on an HTML browser and Figure 3 shows how a WML-enabled phone should render. As you can see, in both cases the patient's name, room number, and status are displayed.

Figure 2

Figure 3

This concludes a brief tour of creating customized controls and device adapters for use with the Mobile Internet Toolkit. By mastering these basic principles you can unlock the full potential of control customization for mobile devices of all kinds.

Author Bio
Christopher Frenz is the author of Visual Basic and Visual Basic .NET for Scientists and Engineers (Apress) and is pursuing his doctorate in biocomputing. In his current research Christopher uses neural networks to model biological systems and develops Web-based scientific applications. cfrenz@att.net

	


Listing 1: The custom label control class


using System;
using System.Web.UI.MobileControls;


namespace CustomLabel
{
    /// <summary>
    /// Simple Custom Mobile Control
    /// </summary>
    /// 
    public class CLabel : MobileControl
    {
        private string pname, room, status;
        public CLabel()
        {
            Pname="";
            Room="";
            Status="";
        }
        public string Pname
        {
            get
            {
                return pname;
            }


            set
            {
                pname = value;
            }
        }


        public string Room
        {
            get
            {
                return room;
            }
            set
            {
                room=value;
            }
        }
        public string Status
        {
            get 
            {
                return status;
            }
            set
            {
                status=value;


            }
        }
    }
}


Listing 2: The HTML adapter class


using System;
using System.Web.UI.MobileControls;
using System.Web.UI.MobileControls.Adapters;
using CustomLabel;


namespace CustomLabel.Adapters
{
    /// <summary>
    /// HTML Adapter for Custom Control
    /// </summary>
    public class CLHTMLAdapter: HtmlControlAdapter
    {
        protected new CLabel Control
        {
            get
            {
                return(CLabel)base.Control;
            }
        }
        public override void Render(HtmlMobileTextWriter
writer)
        {
            writer.EnterStyle(Style);
            writer.WriteLine("Patient: " + Control.Pname + "</p>");
            writer.WriteLine("<p> Room: " + Control.Room + "</p>");
            writer.WriteLine("<p> Status: " +
Control.Status);
                    writer.ExitStyle(Style);
        }
    }
}



Listing 3: The WML Adapter Class

using System;
using System.Web.UI.MobileControls;
using System.Web.UI.MobileControls.Adapters;
using CustomLabel;


namespace CustomLabel.Adapters
{
    /// <summary>
    /// WML Adapter for Custom Control
    /// </summary>
    public class CLWMLAdapter: WmlControlAdapter
    {
        protected new CLabel Control
        {
            get 
            {
                return(CLabel)base.Control;
            }
        }
        public override void Render(WmlMobileTextWriter
writer)
        {
            writer.EnterStyle(Style);
            writer.RenderText("Patient: " + Control.Pname);
            writer.WriteLine("</p>");
            writer.Write("<p>");
            writer.RenderText("Room: " + Control.Room);
            writer.WriteLine("</p>");
            writer.Write("<p>");
            writer.RenderText("Status: " + Control.Status);
                    writer.ExitStyle(Style);
        }
    }
}




Listing 4: Edited WebForm.aspx


<%@ Register TagPrefix="CustomLabel" Namespace="CustomLabel"
Assembly="CustomLabel" %>
<%@ Page language="c#" Codebehind="MobileWebForm1.aspx.cs"
Inherits="MobileWebApplication2.MobileWebForm1" AutoEventWireup="false" %>
<%@ Register TagPrefix="mobile" Namespace="System.Web.UI.MobileControls"
Assembly="System.Web.Mobile, Version=1.0.3300.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a" %>
<meta name="GENERATOR" content="Microsoft Visual Studio 7.0">
<meta name="CODE_LANGUAGE" content="C#">
<meta name="vs_targetSchema"
content="http://schemas.microsoft.com/Mobile/Page">
<body Xmlns:mobile="http://schemas.microsoft.com
    /Mobile/WebForm">
    <mobile:Form id="Form1" runat="server">
        <CustomLabel:CLabel id="CLabel1" runat="server"
Status="Stable" Room="23" Pname="John
Doe"></CustomLabel:CLabel>
    </mobile:Form>
</body>


Listing 5

    <mobileControls 
		sessionStateHistorySize="6"
cookielessDataDictionaryType="System.Web.Mobile.CookielessData">
    
 <!-- applications which inherit the cookielessDataDictionaryType can disable it
 by setting it to an empty string "" -->
    <device
    name="CustomHtmlDeviceAdapters"
	predicateClass="System.Web.UI.MobileControls.Adapters.HtmlPageAdapter"
	predicateMethod="DeviceQualifies"
	pageAdapter="System.Web.UI.MobileControls.Adapters.HtmlPageAdapter">

    <control
    name="System.Web.UI.MobileControls.Panel"
	adapter="System.Web.UI.MobileControls.Adapters.HtmlPanelAdapter" /> 
			.
			.
			.
    <control
    name="System.Web.UI.MobileControls.MobileControl"
	adapter="System.Web.UI.MobileControls.Adapters.HtmlControlAdapter" />
    <control
	name="CustomLabel.CLabel,CustomLabel"
	adapter="CustomLabel.Adapters.CLHTMLAdapter,CustomLabel" />
    </device>

    <device
    name="CustomUpWmlDeviceAdapters"
	inheritsFrom="CustomWmlDeviceAdapters"
	predicateClass="System.Web.UI.MobileControls.Adapters.UpWmlPageAdapter"
	predicateMethod="DeviceQualifies"
	pageAdapter="System.Web.UI.MobileControls.Adapters.UpWmlPageAdapter">
    </device>

    <device
    name="CustomWmlDeviceAdapters"
	predicateClass="System.Web.UI.MobileControls.Adapters.WmlPageAdapter"
	predicateMethod="DeviceQualifies"
	pageAdapter="System.Web.UI.MobileControls.Adapters.WmlPageAdapter">

    <control
    name="System.Web.UI.MobileControls.Panel"
	adapter="System.Web.UI.MobileControls.Adapters.WmlPanelAdapter" />
			.
			.
			.
    <control
    name="System.Web.UI.MobileControls.MobileControl"
	adapter="System.Web.UI.MobileControls.Adapters.WmlControlAdapter" />
    <control
	name="CustomLabel.CLabel,CustomLabel"
	adapter="CustomLabel.Adapters.CLWMLAdapter,CustomLabel" />
    </device>

    <device
    name="CustomChtmlDeviceAdapters"
	inheritsFrom="CustomHtmlDeviceAdapters"
	predicateClass="System.Web.UI.MobileControls.Adapters.ChtmlPageAdapter"
	predicateMethod="DeviceQualifies"
	pageAdapter="System.Web.UI.MobileControls.Adapters.ChtmlPageAdapter">
			.
			.
			.
    </device>
        
        </mobileControls>

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.

  E-mail: info@sys-con.com