Introduction
We will build a simple currency converter using a converter web service from start to finish for the Windows Phone 7 using Microsoft Visual Studio Express 2010 for Windows Phone.
Background
Before we begin, you need to download and setup the Windows Phone Developer Tools. Michael Crump has a great step by step tutorial on setting up everything you need to develop for Windows Phone 7. You can find it here.
You might also want to go through the tutorial in the link to build a basic Phone 7 app to get you up to speed.
Using the Code
Now that you have everything set up, let's start building the currency converter application.
Open Visual Studio 2010 for Phone 7 and from the File Menu, select New Project. You should see this window...
From Visual C#, select Windows Phone Application and name it SimpleCurrencyConverter
and click ok.
You should see the following environment. If you cannot see the properties window , press Ctrl+W+P. You can also go to View > Other Windows > Properties Window to view the properties window.
Click on page name and in the properties window Set the Text to Currency Converter and Font Size to 48.
We need four TextBlocks, two TextBoxes, two drop down lists and one button for our Currency Converter.
You can either drag and drop the four textblocks from the toolbox or drag one and then copy and paste the other three.
Drag and drop two Textboxes from the toolbox and name the first one txConvertedFrom
and the second one txtConvertedTo
. Set the width
to 40
. Note that Visual Studio gives you some guidelines which help you align your controls. Play around with it and resize and align them as you wish.
Now this is where it gets a little tricky, our trusted dropdown list control which you've probably used a million times if you've worked for any length of time on ASP.NET is nowhere to be found in the toolbox. This is apparently because of it not fitting in with the "Metro UI". But, it is still possible to add it from the code. Please be aware that Microsoft guidelines do not recommend using the dropdownlist control. But, since we need a control to bind our webservice data, we will use it for now.
Add the following to your Mainpage.xaml.
<ComboBox ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding ElementName=ConverterPage, Path=Locations}"
Margin="179,139,70,450" Name="cmbCurrFrom">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock FontSize="30" Foreground="Black" Text="{Binding Path=Location}"></TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox ItemsSource="{Binding ElementName=ConverterPage, Path=Locations}"
Margin="179,223,70,370" Name="cmbCurrTo"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock FontSize="30" Foreground="Black" Text="{Binding Path=Location}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Add a button and name is btnConvert
and change its content to "Convert
".
Rename the textblock
s and arrange them as you wish to make it look pretty. As you can see, I haven't done that great of a job prettying it up. ;)
Hope you do a better job. It should look something like this ...
We also need to limit the users from entering alphabets into the converter from text box. First set the Text to an empty string (Text=""
) for your two textboxes. Microsoft provides us with a few different keyboard layouts depending on the context that we are using the text box. This can be set using the Input Scope of your textbox. You can read more about input scope here, here and here.
We still have one problem. Even with the input scope set, the users can still enter special characters into the textbox. We will add this check on the textchanged
event, only letting the users enter numbers.
I found this quick and dirty code that checks for numbers here. Add this method to your MainPage.xaml.cs.
public void txtConvertedFrom_TextChanged(object sender, TextChangedEventArgs e)
{
bool bNeedToUpdate = false;
StringBuilder szNumbersOnly = new StringBuilder();
TextBox textSource = sender as TextBox;
if (null == textSource)
return;
foreach (char ch in textSource.Text)
{
if (("0123456789").Contains(ch.ToString()))
{
szNumbersOnly.Append(ch);
}
else
{
bNeedToUpdate = true;
}
}
if (bNeedToUpdate)
{
textSource.Text = szNumbersOnly.ToString();
textSource.SelectionStart = szNumbersOnly.Length;
}
}
Hook this up to the textchanged
event of your textbox
.
<TextBox Height="72" HorizontalAlignment="Left" Margin="179,26,0,0"
Name="txtConvertedFrom" Text="" VerticalAlignment="Top" Width="200"
TextChanged="txtConvertedFrom_TextChanged" >
Now, we will populate the dropdownlist
s with the country names. We will use a free webservice to populate the dropdownlist
s and also to get the conversion rates.
First, we need to add the service reference to our project. In your solution explorer, right click on References and click on Add Service Reference.
In the window that pops up, enter the web service URL http://www.webservicex.net/CurrencyConvertor.asmx?WSDL in the address box. Enter ConverterService
in the NameSpace textbox
. Click GO. You should see a list of services. Click OK.
Now we need to populate our dropdownlist
s with the countries/currencies list from the Currency Converter Web Service. We will do this using as Observable Collection. You can read about Observable Collections here.
Add this reference to your page:
using System.Collections.ObjectModel;
We need to add a "LocationUnit
" class to setup the Observable Collection.
Add this code within your namespace:.
public class LocationUnit
{
public string Location { get; set; }
public string URL { get; set; }
}
Add the following code at the beginning of your class, before your constructor.
public static readonly DependencyProperty _locations =
DependencyProperty.Register("Locations",
typeof(ObservableCollection<locationunit>), typeof(PhoneApplicationPage),
new PropertyMetadata(null));
public ObservableCollection<locationunit> Locations
{
get { return (ObservableCollection<locationunit>)GetValue(_locations); }
set { SetValue(_locations, value); }
}
Initialize the ObservableCollection
in your constructor.
InitializeComponent();
Locations = new ObservableCollection<locationunit>();
Now we'll populate the dropdownlist
s with the countries/currencies list from the Currency Converter Webservice.
There is one little problem with this webservice
. It returns the currencies list as an enum
, which we can't bind to the dropdown. We need to convert it into a string
array. We will use a helper class to convert the enum
into a string
array.You can find a pretty good example here.
Add this within your CurrencyConverter
namespace:
public static class EnumHelper
{
public static string[] GetNames(Type enumType)
{
FieldInfo[] fieldInfo = enumType.GetFields(
BindingFlags.Static | BindingFlags.Public);
return fieldInfo.Select(f => f.Name).ToArray();
}
public static string[] GetNames(Enum e)
{
List<string> enumNames = new List<string>();
foreach (FieldInfo fi in e.GetType().GetFields(
BindingFlags.Static | BindingFlags.Public))
{
enumNames.Add(fi.Name);
}
return enumNames.ToArray<string>();
}
}
Now we'll add the method that populates the dropdownlist
s:
public void GetData()
{
foreach (string s in EnumHelper.GetNames(typeof(ConverterService.Currency)))
{
LocationUnit unit = new LocationUnit()
{
Location = s,
URL = s
};
Locations.Add(unit);
}
}
Call this method in your constructor:
public MainPage()
{
InitializeComponent();
Locations = new ObservableCollection<locationunit>();
GetData();
}
We need to bind the two dropdownlist
s to our collection
. Add this to your dropdown
s in your XAML files.
<combobox scrollviewer.verticalscrollbarvisibility="Auto">
ItemsSource="{Binding ElementName=ConverterPage, Path=Locations}"
Margin="179,139,70,450" Name="cmbCurrFrom">
Add the Name
property at the top of your XAML:
<phoneapplicationpage x:class="CurrencyConverter.MainPage" x:name="ConverterPage">
Now run your application and you should see your dropdownlist
s populated with the currency names. Now we need to write code to call the webservice
when the user clicks the convert button to get the conversion rate between the two selected currencies. Add these two methods to your MainPage.xaml.cs file.
private void btnConvert_Click(object sender, RoutedEventArgs e)
{
ConverterService.CurrencyConvertorSoapClient aobClient =
new ConverterService.CurrencyConvertorSoapClient();
aobClient.ConversionRateCompleted +=
new EventHandler<converterservice.conversionratecompletedeventargs>(
aobClient_ConversionRateCompleted);
LocationUnit selectedLocationFrom = (
from c in Locations where c.Location == ((
LocationUnit)cmbCurrFrom.SelectedItem).Location select c).First();
LocationUnit selectedLocationTo = (
from c in Locations where c.Location == ((
LocationUnit)cmbCurrTo.SelectedItem).Location select c).First();
ConverterService.Currency currFrom = (
ConverterService.Currency)Enum.Parse(typeof(ConverterService.Currency),
selectedLocationFrom.Location, true);
ConverterService.Currency currTo = (ConverterService.Currency)Enum.Parse(
typeof(ConverterService.Currency), selectedLocationTo.Location, true);
aobClient.ConversionRateAsync(currFrom, currTo);
}
void aobClient_ConversionRateCompleted(object sender,
ConverterService.ConversionRateCompletedEventArgs e)
{
double adblResult = Convert.ToDouble(txtConvertedFrom.Text) * e.Result;
txtConvertedTo.Text = adblResult.ToString();
}
The first method handles the button click event. We create a Client
object for the webservice
and call the ConversionRate
method to get the conversion rate between the two selected currencies. Since the request is asynchronous, we need a method to handle the event when the webservice
sends us the conversion rate. The aobClient_ConversionRateCompleted
handles this event. We multiply the conversion rate with the amount entered and set the value of the g converted to textbox
with this amount. Open MainPage.xaml and hook up the buttonclick
event to the method we just wrote.
<button content="Convert" height="72" horizontalalignment="Left" margin="29,298,0,0"
name="btnConvert" verticalalignment="Top" width="160"
click="function click() { [native code] }">
</button>
Run your application, enter an amount, select two currencies and click convert.
And... we are done! Happy coding!
History
- 15th November, 2010: Initial post