Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Windows Mobile Location ComboBox Controls

0.00/5 (No votes)
30 May 2009 1  
A collection of pre-filled Country, Region, and City comboboxes for the .NET Compact Framework.

Introduction

This article shows how to create a set of self-contained ComboBox controls that display international country, region, and city selections from pre-defined, non-database lists. The controls fit in small size DLLs that do not require Compact SQL Server to execute.

Background

I was working on a WM6 application that asked the user for demographic data such as Country, State/Province/Region, and City. The data would eventually be transmitted to a Web Service so I wanted standardized responses. Therefore, I had to provide the list of locations.

Users do not like to scroll through long lists of thousands of states and cities. I wanted the controls to be smart enough to rebuild Region and City lists when a new Country or Region was selected. If you selected "United States > Michigan", I only wanted Michigan cities on the CityComboBox.

WM6LocationComboBox/CountryRegionCity.jpg

I did not, however, want to rely on a database that required the Microsoft SQL Server Compact Framework. It did not make sense that users had to load a large framework on their mobile device just to implement a small feature. Nor did I want to integrate with an external Web data source, as internet connections are not always possible in a mobile environment.

I found a great source of countries, regions, and cities at GeoBytes.com. I did a little massaging of the data to trim it to the smallest size possible. Instead of adding it to a database, I embedded the CSV files directly into the controls so that only the DLL need be distributed.

Using the code

The solution is split into two projects. The CountryRegionComboBox project provides two ComboBox controls, Country and Region. It does not provide the City ComboBox, as that adds a considerable amount of data. You can use this assembly when you do not need cities and wish to conserve precious mobile disk space.

The CountryRegionCityComboBox includes a 408 KB list of cities. I was able to trim it down a little by combining identically named cities, listing their Region IDs together. If you need the cities and don't mind the extra size, use this assembly.

Embedding the lists

The controls read the embedded data files using System.Reflection.Assembly and the GetManifestResourceStream() method. The CSV files are set as Embedded Resources so they are included in the DLL at compile time.

// Get the executing assembly
System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();

// Get the embedded resource file and create a stream.
Stream CountryFileStream = 
       asm.GetManifestResourceStream("CountryRegionCityControls.Countries.csv");

Cross-control events

When you select a new country, the Country control needs to fire an event that is intercepted by the Region control. The Region control will then rebuild its list to display the regions, states, provinces, etc., of the selected country.

To do this, I used static classes that fired events for each control. Since the classes are static, there is only one implementation of each that is accessable by all controls. If two controls are on the same form, one will trigger events in the other without either of them being aware of the other.

public static class DetectCountryChange
{
    public static event CountryChangedDelegate CountryChanged;
    public static void FireCountryChanged(Country Country)
    {
        if (CountryChanged != null)
            CountryChanged(new CountryChangedEventArgs(Country));
    }
}

To subscribe to the CountryChanged event, you add the event subscription to the Region control's constructor:

public RegionsComboBox()
{
    InitializeComponent();
    // Attach to the CountryComboBox CountryChanged event
    // to trigger region list rebuild.
    DetectCountryChange.CountryChanged += 
      new CountryChangedDelegate(DetectCountryChange_CountryChanged);
}

When the CountryComboBox changes, it calls the FireCountryChanged() method, which triggers the CountryChanged event that is intercepted by the RegionsComboBox.

History

  • 2009.05.29 - Initial submission.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here