From the March 2002 issue of MSDN Magazine

MSDN Magazine

Windows CE

Develop Handheld Apps for the .NET Compact Framework with Visual Studio .NET

Larry Roof
This article assumes you're familiar with Visual Basic .NET or C#
Level of Difficulty     1   2   3 
Download the code for this article: NETCF.exe (228KB)
SUMMARY Smart Device Extensions (SDE) for Visual Studio .NET allow programmers to develop applications for the .NET Compact Framework, a new platform that maintains many of the features of the .NET Framework in a version optimized for handheld devices. This article shows how SDE provides access through Visual Studio .NET to a variety of .NET classes for devices running Windows CE, including classes for creating user interfaces. Data access classes and Web Services for the .NET Compact Framework are also explained. Following that overview, a sample Web Service called XMLList is built. Then the UI—the XMLList client-side application—is created.
 

T he Microsoft® Smart Device Extensions (SDE) for Visual Studio® .NET provide developers with a scaled-down implementation of the Microsoft .NET Framework called the .NET Compact Framework. This smaller model offers a functional subset perfect for Windows® CE-powered devices while still allowing developers to create applications with either Visual Basic® .NET or Visual C#™ .NET. (While you can still use C++ to create applications for Windows CE-based devices, only Visual Basic and C# can make use of the .NET Compact Framework.) SDE works as a plug-in for Visual Studio .NET. Because it operates inside of Visual Studio .NET, SDE can take advantage of the rich development features of the Visual Studio IDE.
      In this article, I will introduce you to SDE, point out the key features of the .NET Compact Framework, and walk you through the construction of a mobile application that incorporates Web Services and XML. In my description, I'll focus on Visual Basic .NET since that's the language I used to develop the sample application presented in this article. The information and techniques that I'll present here apply to applications developed in the C# language as well.
      Please note that the concepts and examples presented in this article were tested with a prerelease version of Visual Studio .NET and therefore they may not be compatible with the final release version. Final features are subject to change.

The .NET Compact Framework

      In developing applications with SDE, you are targeting the .NET Compact Framework, which simplifies application development on smart devices. The .NET Compact Framework was designed to be easily ported to other platforms, whether those platforms were created by Microsoft or third-party vendors. What does this mean to you? It means that the apps you create today to run on a Pocket PC could just as easily run on other platforms such as a cell phone or another vendor's PDA, provided that a version of the .NET Compact Framework has been implemented for that platform.
      The classes in the .NET Compact Framework have an interface identical to their .NET Framework equivalents with the exception of functionality that is not supported because of size constraints, performance issues, or limitations in the target operating system. Class behaviors, properties, methods, and enumeration values are the same under both versions of the .NET Framework. Before I describe how I've used the Compact Framework in my sample application, I'll give you a brief overview of some of the classes you'll find in the Class Library.

Classes in the Class Library

      The compact version of the .NET Framework implements a subset of the System.Windows.Forms and System.Drawing classes. These classes can be used to construct rich, Windows CE-based user interfaces for device applications. Much of the interaction with these classes is managed for you by the Windows Forms designer component of Visual Studio .NET. The implementation of Windows Forms under the .NET Compact Framework includes support for forms, bitmaps and menus, most controls in the .NET Framework, and the ability to host third-party controls.
      There are classes that allow you to easily incorporate data, whether the source is a relational or nonrelational data source. The implementation of both data and XML classes under the .NET Compact Framework is a subset of those found in the .NET Framework, with the most commonly used functionality of both included in the Compact version.
      The .NET Compact Framework also provides a subset of the Web Services functionality offered in the .NET Framework. Most significantly, using Visual Studio .NET and SDE you can create applications that allow you to easily consume XML Web Services. While you can create both Web Services and client applications that consume Web Services using Visual Studio .NET, the .NET Compact Framework supports only the development of the client component at the present time.
      Programmers using Visual Basic will appreciate the fact that Visual Basic .NET makes liberal use of helper functions that are located in the Microsoft.VisualBasic namespace. The version that is part of the .NET Compact Framework offers a subset of these functions as well. The functions included in the Microsoft.VisualBasic namespace are considered a core part of the language, and in fact include many of the keywords from previous versions of Visual Basic.
      The .NET Compact Framework also provides support for the basic Graphical Device Interface (GDI) drawing elements including bitmaps, brushes, fonts, icons, and pens.
      And finally, the .NET Compact Framework provides a set of base classes that expose a wide range of functionality. This underlying infrastructure enables you to write applications for .NET that incorporate multithreading, take advantage of available network resources, and help you work with files.

The XMLList Sample Application

      Now that you have an overview of the .NET Compact Framework, take a look at my XMLList application which is illustrated throughout this article. The XMLList application demonstrates two key features of the .NET Compact Framework—Web Services and XML.

Figure 1 The List Structure
Figure 1 The List Structure

      XMLList is a Pocket PC-based application that provides list management capabilities. This is no ordinary list program, though. Not only can lists be created locally on the device (as you would expect) but the application can also save and retrieve lists from a server via a Web Service. This feature enables one individual to build a list and store it on a server so that it can be picked up by another individual. Each list, whether it is stored locally or on the server, is stored by persisting XML to a file. An example of the XML list structure is shown in Figure 1. I'll describe the Web Service first and following that, I'll discuss the client application.

The XMLList Web Service

      One of the great features of the .NET Framework is the ease with which you can create Web Services. Starting with only the ASP.NET Web Service project template and adding a few simple functions, I was able to provide capabilities for storage, retrieval, and management of lists by remote clients. .NET also makes it easy to use XML with ADO.NET DataSets, as the examples in this section will show. In my example I could just as easily retrieve data from an enterprise-based server using ADO.NET and forward that data to a client as a DataSet.
      The Web Service component of the XMLList application is fairly straightforward. The shell of this service was created using the ASP.NET Web Service project template. To this project I added methods to save, load, delete, and list the available lists. I'll describe each of these methods briefly in the following paragraphs.
      The SaveList method accepts two arguments (the name of the list and the contents of the list), which are passed as an ADO.NET DataSet. The WriteXML method of the DataSet object is used to persist the contents to an XML file as shown here.

  <WebMethod()> Public Function SaveList(ByVal NameOfList _
  
As String, ByVal ListToSave As DataSet) As Boolean
' Saves a list delivered as a dataset as an XML file.

ListToSave.WriteXml(Server.MapPath(NameOfList))
SaveList = True

End Function

 

      The LoadList method accepts a single argument—the name of the list to load. It returns the requested list in an ADO.NET DataSet. The list is read from a file on the server using the ReadXML method of the DataSet object. The MapPath method of the Server object is used to instruct the Web Service to look in its root directory for the list. For simplicity, I elected to store the lists in the same folder as my Web Service. They could easily be moved to another location at a later time.

  <WebMethod()> Public Function LoadList(ByVal _
  
NameOfList As String) As DataSet
' Returns the selected list as a dataset.
Dim dsList As DataSet

' Create, load and return the dataset.
dsList = New DataSet()
dsList.ReadXml(Server.MapPath(NameOfList))
LoadList = dsList

End Function

 

      The DeleteList method handles the removal of lists from the server. Within this function, the Kill method of the Microsoft.VisualBasic namespace is called to perform the file deletion.

  <WebMethod()> Public Function DeleteList(ByVal _
  
NameOfList As String) As Boolean
' Deletes a list from the server.
Dim strPath As String

' Build the path for the file and remove it.
strPath = Server.MapPath(NameOfList)
Microsoft.VisualBasic.Kill(strPath)

' Respond successfully.
DeleteList = True

End Function

 

      The Pocket PC component of the XMLList application requests a list of lists stored on the server by calling the ListLists method. This function is by far the most complicated of the four functions. To simplify this feature, I use an existing empty XML file with a preconfigured format. The effect of loading this empty list into a DataSet is that the DataSet will be configured with the appropriate list structure. All that is left to do is to use the Dir method of the Microsoft.VisualBasic namespace in order to load the list of available files, just as you would have used the Dir function in earlier versions of Visual Basic. A variable number of repetitive calls are made to this method until all of the list file names have been loaded into the DataSet, as you can see in Figure 2.

Figure 3 XMLList in Internet Explorer
Figure 3 XMLList in Internet Explorer

      Figure 3 shows the XMLList Web Service in Microsoft Internet Explorer. Accessing your Web Service from Internet Explorer enables you to quickly verify the functionality of your service.

The XMLList Client Application

      The client component of the XMLList application illustrates two key points of SDE for Visual Studio .NET: the functionality provided through the .NET Compact Framework and the similarity between developing desktop or server applications and creating applications for the Pocket PC.

Figure 4 Management Mode
Figure 4 Management Mode

      The XMLList client has two interface modes: list management mode (see Figure 4) and list usage mode (see Figure 5).

Figure 5 Usage Mode
Figure 5 Usage Mode

The Client Project in Visual Studio .NET

      With the exception of the testing process, developing applications that target the Pocket PC is very similar to creating Windows-based applications. The code used to build the XMLList client could be used as is to create a desktop version of the client. In this section I'll describe the templates, tools, and controls that are available for developing applications that run on the client.
      When SDEs are installed, they add a set of templates to both the Visual Basic and Visual C# project folders within the Visual Studio .NET New Project dialog. Four templates are added to the Visual Basic Projects folder. The first of these templates, the Pocket PC Application template (see Figure 6), provides the basic project configuration required for creating a Pocket PC application. Also shown in Figure 6 are two of the other templates: the Pocket PC Class Library template, which is used to construct class libraries, and the Pocket PC Control Library template, which is used to create controls for use with the .NET Compact Framework. The Windows CE Application template allows you to build a .NET Compact Framework project for any device running Windows CE that supports the .NET Compact Framework.

Figure 6 Pocket PC Templates
Figure 6 Pocket PC Templates

      The Pocket PC project templates, as with all device templates, create the initial files, references, code framework, property settings, and tasks as appropriate for the selected project type. Device templates take into account the target platform, which in turn affects the .NET Compact Framework libraries available for use by the developer.
      Since SDE uses the Visual Studio .NET IDE, the tools available for constructing an interface for a Pocket PC application are identical to those used to build a Windows-based application. Figure 7 shows the forms designer that is being used to develop the XMLList client application.

Figure 7 Visual Studio .NET Designer
Figure 7 Visual Studio .NET Designer

      The primary difference between developing an application that targets the .NET Compact Framework and one that targets the .NET Framework is the absence of a few controls and project components. However, SDE includes a comprehensive set of controls for use with the .NET Compact Framework (see Figure 8).
      SDEs provide a broad set of project items from which to choose. Figure 9 details the supported file types along with their file extension and a brief description.

The Code Behind the XMLList Client

      While the XMLList client requires more coding than the XMLList Web Service, it is by no means complicated. Outside of the straightforward list-building features (adding, updating, and deleting items), the core of the XMLList client centers around loading lists, saving lists, and providing a list of the available lists that are stored either locally or on the XMLList server.
      Providing the user of the XMLList client with a list of lists is handled by the ListLists procedure. This procedure accepts a single argument that then determines whether or not to display the local or server-based lists.
      For local lists, the Dir method of the Microsoft.VisualBasic namespace is used, just as it was in the XMLList Web Service. The only difference is that instead of referencing Server.MapPath, as was done with the Web Service, I use Application.StartupPath to determine where the lists are stored.
      For remote lists, a call is made to the ListLists method of the XMLList Web Service. As I've mentioned earlier, SDEs for Visual Studio .NET allow you to quickly create client applications that consume Web Services, and the process of creating these applications is very similar to that used to create a Windows-based application. You can simply add a Web reference to your Pocket PC project, create an instance of the Web Service object, and then you are ready to call any of the methods exposed through the Web Service.
      The ListLists method exposed by the XMLList Web Service returns a DataSet containing the lists that are present on the server. All that I needed to do was iterate through the DataSet and load the name of each list into the XMLList client display, as you can see in Figure 10.
      How a list is loaded depends upon whether the selected list is stored locally on the Pocket PC or remotely on the XMLList server. Local lists are loaded with the DataSet object's ReadXML method. This method for loading a list is identical to the way it is implemented for the XMLList Web Service and demonstrates how you can utilize your existing Visual Basic .NET skills to create mobile solutions using SDEs.
      Remote lists are loaded by calling the LoadList method of the XMLList Web Service. Whether the list is stored locally or remotely, its contents end up in a DataSet object, which in turn is loaded into the client interface (see Figure 11).
      To save a list, it is first loaded into a DataSet and then written to a file as XML. Loading the DataSet involves nothing more than adding and loading a new record for each item in the list. The process of saving the list to a file is dependent on where the file is stored (locally or remotely). For dealing with local storage, the WriteXML method of the DataSet object is used, just as it was in the SaveList method of the XMLList Web Service. Figure 12 shows that the XMLList client saves lists remotely by calling the SaveList method of the XMLList Web Service.

Building and Testing Your Application

      The process of building applications that target the Pocket PC is very similar to the process used to build desktop applications. However, you have two options for testing an SDE-based application: you can use an emulator or you can test the actual target device. You can easily switch between these two using the menu bar within the Visual Studio .NET IDE, as shown in Figure 13.

Figure 13 Visual Studio .NET Menu
Figure 13 Visual Studio .NET Menu

      While emulation testing has been available since the earliest version of the Windows CE development tools, previous emulators included with the various devices development kits were simply Windows-based applications simulating a device environment. The emulator included with SDE, however, runs a binary image of the device operating system. For all practical purposes, it is a device running inside of Windows. This means that the emulator acts and operates in the way you can expect your device to function. This type of emulation is referred to as true emulation; that is, the emulation environment provides full support of the actual device's functionality. This emulator is a separate and complete instance of a virtual machine. Any operating system calls that are made by an application from within the emulator are not patched through to the host operating system. The SDE emulator can be used with either Windows 2000 or Windows XP.
      One of the benefits of having SDEs operate within Visual Studio .NET is that SDE can make use of its native functionality. One example of this is the scripting capabilities included with Visual Studio .NET. SDE developers can use these scripting capabilities in conjunction with the new emulator in order to automate the application testing process.
      Testing applications for localization issues is much easier using the emulator. By obtaining an image for each localized version of the target operating system, you can determine how your application reacts without needing to acquire multiple hardware devices.

Working with Emulator Images

      Images running in the emulator act like the actual device. Applications running in the emulator can access the network, consume Web Services, install software, and perform any other action, just as you could do on a device. Not only does the emulator included with SDE provide an accurate representation of the actual device, it also allows you to modify, save, and restore custom configurations of operating system images.
      Operating system images can be customized by including additional software, files, and registry settings. These customized images can be saved and restored for use with the emulator to meet your development needs.
      Operating system images running in the emulator can also be accessed and configured using ActiveSync®, just as you would a device. Upon closing the emulator, you can choose to save or discard changes made to an image.
      Using the reset command within the emulator returns an image to its original state. If it is a default image, it will revert to its shipped state. If it is a developer-saved image, it will revert to the way it appeared the last time the image was saved.
      In order to use a previously saved image, you simply need to select the desired image from the target device dropdown box from within the Visual Studio .NET IDE. Images not included with SDE will be delivered with device kits (formerly known as SDKs). This allows the emulator to support future versions of Windows CE as they become available.
      While the new emulator that is included with SDE provides a robust development environment, it should not be used as your sole means of testing. Final testing should always be performed on the target device. The SDE copies your application and the required supporting components to your device, launches your application, and enables you to debug your logic using the Visual Studio .NET IDE.

Conclusion

      For the developer who is already experienced in creating applications using Visual Studio .NET, creating mobile solutions has just been made simpler. SDE and the .NET Compact Framework allow you to use your existing skills to create robust mobile solutions. You have all of the key components available for your use: multiple languages supported by Visual Studio .NET, XML, ADO .NET, Web Services, and more.

For related articles see:
First Look at Smart Device Extensions
Extreme XML columns on MSDN Online

For background information see:
https://msdn.microsoft.com/xml/
https://msdn.microsoft.com/WebServices/

Larry Roof is a partner at tonked (https://www.tonked.com), which specializes in training, consulting, and product development of mobile solutions. He is the author of Professional Visual Basic Windows CE (Wrox Press, 1998) and writes a monthly column on mobile development called "Two for the Road" on MSDN Online. You can reach Larry at lroof@tonked.com.