Home > Articles > Programming > Windows Programming

Mobile Device Development

📄 Contents

  1. Sample Application Walkthrough
  2. About this Article
Scott Worley shows you how to use the Mobile Device Development Toolkit with ASP.NET to create a relatively simple data-driven application.
Scott Worley is the author if Inside ASP.NET
Like this article? We recommend

Like this article? We recommend

This article presents you with a mobile phone application. The application is a simple interface to a task management database. It allows you to see what tasks are on the system, their status, and the details of the tasks. This simple application and code is for demonstration purposes only.

Requirements for Development

To develop mobile applications with .NET, you must download and install the following software components:

  1. Windows 2000 Professional/Server/Advanced Server OS

  2. .NET framework Software Development Kit (SDK) Beta 2 (http://www.gotdotnet.com)

  3. .NET Mobile Web SDK Beta 2 (http://www.gotdotnet.com)

  4. Your favorite WAP simulator (The author uses the UP.SDK from http://www.Phone.com)

  5. SQL Server 2000

You also must create a database on SQL Server called "dnaMobileData" and restore the dna01_bkup.dat file to it. If you create a database with a different name, you will have to change the connection string values in the source code.

Terminology Overview

This article uses slightly different terminology than what you may be used to when referring to ASP.NET Web Forms. This is due to the nature of mobile device development, specifically in the areas of WAP/WML, which is the code generated by this article.

Basically, when referring to a Web Form in mobile device terms, it is called a card because a mobile device web page can have multiple forms or cards. The web page itself is referred to as a deck because it holds a collection of one or more cards.

Sample Application Walkthrough

To begin, a menu is displayed. This menu is actually a list of links used as menu options. Once one of the links is selected, a list of tasks relating to that option is displayed. The task details are presented to the user of the device. All the information is gathered from a SQL Server database and all pages are dynamically generated. That's all there is to it. You will see, however, code examples showing basic presentation, navigation, and data access.

Card 1—Default Card

When you access the application for the first time, you see a card that displays a menu. This menu lists the current totals of All Tasks, Tasks Not Started, Tasks In Progress, and Tasks Completed. The totals are generated using a Database query. The first screen of the application is shown in Figure 1.

Figure 1 The first screen of the application

Now that you know what the applications initial card is going to look like, it's time to see the code for it. Listing 1, shows the presentation code for the card:

Listing 1 Presentation code for the card

01 <%--Default card to display on mobile device--%>
02 <Mobile:Form ID="cardHome" RUNAT="server">
03 <strong>
04  <Mobile:Label RUNAT="server" >
05   Simple Task Manager
06  </Mobile:Label>
07 </strong>
08 <br/>
09 <Mobile:Link RUNAT="server" ID="linkListAll" 
10     NavigateUrl="#cardListAll"> </Mobile:link>
11 <Mobile:Link RUNAT="server" ID="linkListNotStarted"     
12     NavigateUrl="#cardListNotStarted"> </Mobile:link>
13 <Mobile:Link RUNAT="server" ID="linkListInProgress" 
14    NavigateUrl="#cardListInProgress"></Mobile:link>
15 <Mobile:Link RUNAT="server" ID="linkListComplete" 
16    NavigateUrl="#cardListComplete"></Mobile:link>
17 </Mobile:Form>

Line 01, is a server-side comment, which is not rendered to the mobile device. It is best to use server-side comments as opposed to client-side HTML comments to keep the size of a card to a minimum. A mobile device has to work with a limited bandwidth connection, which is very rarely much faster than 15k. Line 02 starts the definition of the card. It is recommended that you give your mobile forms an ID because the ID can be used for navigational purposes (more on this and the runat=server element later in the article). The latter is required to ensure that the control is processed server-side—the same way as a regular ASP.NET Web Form.

On line 04, a Label control is used to display the title of the application. The Label control is used in one of two ways: either to display static text, or to act as a placeholder for static text. On lines 09-17 is a group of Link controls. These controls are used for navigational purposes. Note that the control itself does not have any display text because the control's label text is generated at runtime, using the Page_Load event. The next element of note is the Target element, which can be used to hold the URL of another page, or as done here, the name of a card in the deck being processed (prefixed by a # symbol). The card must exist in the source code file being processed.

The next bit of code to look at is the Page_Load subroutine (see Listing 2). This is called once the mobile device receives the deck of cards from a web server. This subroutine is pretty basic. All it does is call another subroutine that is used to populate all of the controls, for all of the cards in the deck—in this case, four Link controls on the first card and a group of List controls, which are on cards later in the application.

Listing 2 Page_Load Subroutine

01 Sub Page_Load(Source As Object, E As EventArgs)
02  GetDataAndBindData()
03 End Sub

Listing 3 is a little long, but it is not as bad as it first seems. Let's see exactly what is being done here.

Listing 3 Binding Data to the Mobile Controls

01 Sub GetDataAndBindData()
03  Dim myDataSet As New DataSet()
04  Dim myCommand As SqlDataAdapter
05  Dim myConn As SqlConnection
06  Dim mySQLString As String
08  myConn = New SQLConnection("Data Source=localhost;User Id=sa;password=;
Initial Catalog=dnaMobileData")
10  mySQLString = "SELECT * FROM vwAllUserTasks"
11  myCommand = New SqlDataAdapter(mySQLString, myConn)
12  myCommand.Fill(myDataSet, "All")
14  mySQLString = "SELECT * FROM vwAllUserTasks WHERE StatusName='Not Started'"
15  myCommand = New SqlDataAdapter(mySQLString, myConn)
16  myCommand.Fill(myDataSet, "NotStarted")
18 mySQLString = "SELECT * FROM vwAllUserTasks WHERE StatusName='In Progress'"
19 myCommand = New SqlDataAdapter(mySQLString, myConn)
20 myCommand.Fill(myDataSet, "InProgress")
22 mySQLString = "SELECT * FROM vwAllUserTasks WHERE StatusName='Complete'"
23 myCommand = New SqlDataAdapter(mySQLString, myConn)
24 myCommand.Fill(myDataSet, "Complete")
27  'Bind Controls to dataset data
28  listAll.DataSource = myDataSet.Tables("All").DefaultView
29  listAll.DataTextField = "name"
30  listAll.DataValueField = "id"
31  listAll.DataBind()
33  listNotStarted.DataSource = myDataSet.Tables("NotStarted").DefaultView
34  listNotStarted.DataTextField = "name"
35  listNotStarted.DataValueField = "id"
36  listNotStarted.DataBind()
38  listInProgress.DataSource = myDataSet.Tables("InProgress").DefaultView
39  listInProgress.DataTextField = "name"
40  listInProgress.DataValueField = "id"
41  listInProgress.DataBind()
43  listComplete.DataSource = myDataSet.Tables("Complete").DefaultView
44  listComplete.DataTextField = "name"
45  listComplete.DataValueField = "id"
46  listComplete.DataBind()
48  linkListAll.Text = "All Tasks: (" + listAll.Items.Count.ToString + ")"
49  linkListNotStarted.Text = "Tasks Not Started: 
(" + listNotStarted.Items.Count.ToString + ")"
50  linkListInProgress.Text = "Tasks In Progress: 
(" + listInProgress.Items.Count.ToString + ")"
51  linkListComplete.Text = "Tasks Complete: 
(" + listComplete.Items.Count.ToString + ")"
53 End Sub

Lines 03-06 are just declaring variables and objects required for data access. These should be familiar to anyone who has done ADO.NET development work. Line 08 is used to set-up and create a SQLConnection object, which is used to connect to a SQL server database.

Lines 10 to 12 present a more interesting section of code. These three lines are repeated four times, once for each type of task status listed on the first page. Also if you remember from the application overview at the beginning of this article, I mentioned that after selecting an option from the first card, you would be presented with another card of information that displays all of the tasks for that option. This section of code may be used to create that list as well, which might seem strange.

Why create all of this data up front rather than as it is needed? Why not treat it like a traditional web application? The answer is quite simple: Because multiple cards can be downloaded to a mobile device at on time, all of the cards should act in a disconnected manner. That is to say, once the deck has been downloaded, it should work without requiring access to the web server unless specifically required. This means that any issues dealing with connection latency—or indeed disconnection - do not hamper the operation of the mobile device too much. Because the bandwidth of a mobile device connection is particularly small, the less access to a web server the better.


Normally, single stored procedure would be used to retrieve all of these values, and then bind the resulting data to a mobile:List object, but for reasons of simplicity, I have not done so here.

Back to the code: On line 10, a string is declared to hold a SQL statement that is to be processed by a SQL Server. The statement itself is pretty simple; just return all of the tasks in the database. On line 11, a SQLDataAdapter object is created using the Connection object and the SQL query string created in line 09. Finally, in line 12, the SQL query is processed and its resulting data is stored in a DataSet object that was created on line 03. It's assigned the name of "All", so that we can reference this table of data later in the application.

Lines 14-16 do the same as above. But note that the SQL statement string (line 14) is changed to a query that returns only those tasks that have a status of 'Not Started'. Once the string has been redefined, the SQLDataAdapter is created with the new SQL statement (line 15).

The same process applies for lines 19-21, and lines 23-25. The only differences being the SQL statements and the name of the tables that are being stored in the dataset.

Lines 26-37 setup and bind data to 4 separate List controls, and their data sources, this is done by first assigning a DataSource, and then by assigning the DataTextField and DataValue Field Values as shown below.

28  listAll.DataSource = myDataSet.Tables("All").DefaultView
29  listAll.DataTextField = "name"
30  listAll.DataValueField = "id"
31  listAll.DataBind()

On line 29, the List control sets its datatextfield property to the Name field in the table. The datatextfield property is the value used as an option in the list. On line 30, the datavaluefield sets the ID field in the table. The datavaluefield is used to store the value of an option in the List control. In this case, each name of each task in the database will be an option on the List control and each ID in the database will be the value used for each option. On line 31, the List control is bound to its datasource based on the datatextfield and datavaluefield properties.

This process is repeated for each List control in all the other cards in the deck. Only the List control name and the datasource value are changed to reflect the differing sets of data required.

The final section of code in this subroutine deals with setting the values of the Link controls on the first card. The text property of each Link control simply is assigned to the text label that is to be used, which in this case is a predefined label plus the total number of items in each List control to which data is bound.

Cards 2,3,4 and 5—Listing the Tasks for the Specified Option.

The presentation code for these four cards is essentially the same with the exception of differing IDs (see Figure 2). Therefore, I am only going to walk through the code for the first one (see Listing 4).

Figure 2 The Presentation of cards 2, 3, 4, and 5.

Listing 4 Presentation Code for Card 2

01 <%--Display all Tasks in Database as a Selection List--%>
02 <Mobile:Form ID="cardListAll" RUNAT="server">
04  <strong>
05   <Mobile:Label RUNAT="server" >
06    All Tasks
07   </Mobile:Label>
08  </strong>
09  <br/>
11  <Mobile:List runat=server 
12     id="listAll" OnItemCommand="ListHandler"> </Mobile:List><br/>
14  <Mobile:Link RUNAT="server" 
15     NavigateUrl="#cardHome">Home Page</Mobile:link>
17 </Mobile:Form>

Line 02, defines the card ID. (As stated earlier in the article, you can have many cards in a deck.) The only way to see any cards in the deck (apart from the first one) is to explicitly navigate to them. In the case of this card, navigation is done from the first card in the file through a Link control. Lines 04-08 just render the title of the card to the mobile device's display. Then, on line 10, a List control is defined.

The subroutine identified in the OnItemCommand element will be called. Also notice that no options are defined for this control because they are generated at runtime by the Page_Load event, as shown in the previous section. Finally, on line 14 a Link control is created, which is used to navigate to the first card in the deck. As before, it references the card name in the target attribute of the control.

Card 6—Displaying the Task Information

Line 11 in Listing 4 refers to a subroutine called ListHandler by its onItemCommand attribute. This subroutine is called when an option is selected on the List control. This subroutine is used by all of the cards with a Databound list. Its sole purpose is to connect to the server and download the information on the task that was selected. In a real application you would still use the dataset that was created earlier for this purpose. For this brief tutorial, however, I decided to access the database again, except this time using a SQLDataReader control. The presentation code is listed in Listing 5, and can be viewed in figure 4.

Figure 4 Presentation of Card 6.

Listing 5_Presentation Code for Card 6

01 <Mobile:Form id="CardDisplaySelection" runat=server>
02 <strong>Task Name:</strong>
03 <br/>
04 <Mobile:Label runat=server id="taskName"></Mobile:Label>
05 <br/>
06 <strong>Task Description: </strong>
07 <br/>
08 <Mobile:Label runat=server id="taskDescription"></Mobile:Label>
09 <br/>
10 <strong>Task Staus: </strong>
11 <br/>
12 <Mobile:Label runat=server id="taskStatus"></Mobile:Label>
13 <br/>
<Mobile:Link RUNAT="server" NavigateUrl="#cardHome">Home
15 </Mobile:Form>

In this control, each element of the task that was selected is rendered one after the other. You might find the formatting of the code somewhat strange, but this makes the best possible use of the mobile device screen. As stated at the beginning of this article, this application was designed with mobile phones in mind. Consequently, it renders pretty well on such devices. As before, the Label controls do not render text by themselves. Instead they have their text generated by the ListHandler subroutine shown in Listing 6.

Listing 6_ListHandler Subroutine

Sub ListHandler(ByVal Source As Object, ByVal E As
03  Dim myConn As SqlConnection
04  Dim myCommand As SqlCommand
05  Dim myParam As SqlParameter
06  Dim myReader As SqlDataReader
08  myConn = New SqlConnection("Data Source=localhost;User
      Id=sa;password=;Initial Catalog=dnaMobileData")
09  myConn.Open()
11  myCommand = New SqlCommand("spGetTask", myConn)
12  myCommand.CommandType = CommandType.StoredProcedure
13  myParam = myCommand.Parameters.Add(New SqlParameter("@TaskID", SqlDbType.Int))
14  myParam.Direction = ParameterDirection.Input
15  myParam.Value = E.ListItem.Value
17   myReader = myCommand.ExecuteReader()
19   While myReader.Read()
21    taskName.Text = myReader.Item("name")
22    taskDescription.Text = myReader.Item("description")
23    taskStatus.Text = myReader.Item("statusname")
25   End While
27   myConn.Close()
29   ActiveForm = CardDisplaySelection
31 End Sub

You are now into the final part of code for this application. In lines 03-06, the variables and objects required to read data from the database are set up. On lines 08 and 09, a connection to the database is created and opened. Line 11 defines a SQLCommand object to use with the database. This example calls on the following stored procedure (see Listing 7), which is in the database.

Listing 7_Database stored procedure

02 @TaskID int
03 AS
04 SELECT * FROM vwAllUserTasks WHERE id = @TaskID

As you can see the stored procedure is pretty simplistic. It takes the TaskID as a parameter. The stored procedure uses the TaskID in a simple select query. (The TaskID is the value of the List control option selected.)

On line 12 (Listing 6) the command type of the SQLCommand object is set to stored procedure. Then on line 13 a SQLParameter object is defined as the @TaskID parameter in the stored procedure with a data type of int. Line 14 tells the parameter object that it is holding an input only parameter. Line 15 assigns the parameter's value based on the option value of the passed List control. (The List control is passed to the event handler, which is processing its OnItemCommand event).

On line 17, the stored procedure is executed, which leads us to line 19. That's a simple While loop that reads the next item in the datareader object. If no data is returned by the stored procedure, the While block gets skipped. If there is a returned value, however, the values from the datareader are assigned to the Label controls on the sixth Card. Once this has been done, the sixth card is displayed by setting the mobile device's active card value to the ID of the sixth card.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information

To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.


Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.


If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information

Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.


This site is not directed to children under the age of 13.


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information

If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information

Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents

California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure

Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact

Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice

We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020