2. Connecting to a Web Service
To retrieve current currency exchange rates, you will be using a web service located at www.webservicex.net/CurrencyConvertor.asmx. While there are several ways to connect to a web service and retrieve data,
which draws on the new Microsoft Reactive Extensions, or Rx.NET. Using
Rx.NET makes it easier to follow the flow of execution by the program,
since it abstracts—behind a solid Observer pattern—the complexities of
invoking of a web service asynchronously. Follow these steps to add a
reference to the Currency Conversion service and to wrap the results
returned by that service within Rx.NET.
With
the CurrencyConversion project open, right-click Solution Explorer and
select Add Service Reference. Paste the following URL into the Address field, as shown in Figure 4:
http://www.webservicex.net/CurrencyConvertor.asmx
Once you click the Go button, Visual Studio should be able to locate the CurrencyConverter service.
Change the namespace in the Add Service Reference Page to svcCurrencyConverter and click OK.
Next, you will need to add reference to the assemblies that contain the Rx.NET modules.
To accomplish that, right-click the project name in Solution Explorer, select Add Reference, and add references to Microsoft.Phone.Reactive and System.Observable assemblies.
Switch to the code view for MainPage.xaml (right-click MainPage.xaml and select View Code) and add the following using directive to the top of the page:
using Microsoft.Phone.Reactive;
Create a module-level variable referencing the currency converter web service (this would be a local MainPage
class variable that should be initialized just above the constructor).
Also, declare and initialize a module-level rate variable :
svcCurrencyConverter.CurrencyConvertorSoapClient currencyClient = new
svcCurrencyConverter.CurrencyConvertorSoapClient();
Double dblRate = 0.0;
Within the MainPage()constructor, create an Rx.NET subscription to the CurrencyConverter web service by pasting the following code.
//create subscription to the web service
var currency =
Observable.FromEvent<svcCurrencyConverter.ConversionRateCompletedEventArgs>(currencyClient, "ConversionRateCompleted");
currency.ObserveOn(Deployment.Current.Dispatcher).Subscribe(evt =>
{
dblRate = evt.EventArgs.Result;
txtStatus.Text = "The current rate is 1 " +
lstConvertFrom.SelectedItem.ToString() + " to " + evt.EventArgs.Result.ToString() + " " + lstConvertTo.SelectedItem.ToString();
if (txtAmountToConvert.Text.Length>0)
{
Double decTotal = evt.EventArgs.Result *
Convert.ToDouble(txtAmountToConvert.Text);
txtTotalConverted.Text = txtAmountToConvert.Text + " " +
lstConvertFrom.SelectedItem.ToString() + " = " + decTotal.ToString() + " " + lstConvertTo.SelectedItem.ToString();
}
},
ex => { txtStatus.Text = "Sorry, we encountered a problem: " + ex.Message; }
);
This code creates a subscription
to all of the results returned by the currency converter service. It
processes the results and shows the conversion rates requested on the
screen, including multiplying the total amount to be converted by the
conversion rate.
You are almost done
establishing a connection and retrieving data from the Currency
Converter web service. The one piece that remains to be written is the
invocation of this web service, which, in our example, is done via the
Convert button.
In the design view of MainPage.xaml, double-click the Convert button and change the btnConvert_Click method to look like the following:
private void btnConvert_Click(object sender, RoutedEventArgs e)
{
currencyClient.ConversionRateAsync((svcCurrencyConverter.Currency)
lstConvertFrom.SelectedItem, (svcCurrencyConverter.Currency)
lstConvertTo.SelectedItem);
}
This code invokes the web
service asynchronously and passes it the parameters selected by the user
(currency names only, in our case). Note how we have to properly cast
the parameters to the type expected by the web service (svcCurrencyConverter.Currency
type in our case). The results of this asynchronous invocation are
returned to the application and are processed within the subscription
code just created within the MainPage() constructor code.
With the web service wired
up and the data coming back through the Rx.NET subscription to the
application, the backbone of our application is complete. Now, we have
to introduce navigation between different pages of the application.
3. Adding Page-to-Page Navigation
In the "Building the User Interface"
section, you created three separate pages that make up the application.
However, in the application's present state, only a single (MainPage.xaml)
page is available during runtime. In this section, you will review
navigation between pages in the Windows Phone 7 application.
The envisioned flow of
the application is that a separate "More Stuff" page is available to
users with full licenses; users with trial licenses should see an
"Upgrade" page that prompts them to upgrade. Navigating between pages in
Windows Phone 7 is similar to navigating between web pages: you can use
the same NavigationService.Navigate method and pass it the name of the
XAMLpage within the application to navigate to. This is exactly what
you'll do in the Currency Converter application.
With
the Currency Converter application open, double-click the More Stuff
button and make the btnMoreOptions_Click method look like the one here:
private void btnMoreOptions_Click(object sender, RoutedEventArgs e)
{
//use Microsoft implementation of LicenseInformation class
var lic = new LicenseInformation();
if (lic.IsTrial() == true)
{
NavigationService.Navigate(new Uri("/Upgrade.xaml",
UriKind.RelativeOrAbsolute));
}
else
{
NavigationService.Navigate(new Uri("/MoreStuff.xaml?rate=" +
dblRate.ToString() + "&total=" + txtAmountToConvert.Text,
UriKind.RelativeOrAbsolute));
}
}
Notice how this method uses
the IsTrial method to check whether an application is executing under a
trial or full license, and then it uses the NavigationService.Navigate
method to display the Upgrade.xaml page if IsTrial returns true, and it displays the MoreStuff.xaml page if IsTrial returns false. Note that when you navigate to the MoreStuff.xaml
page, you also pass two parameters to that page. One way of passing
parameters on Windows Phone 7 is identical to parameter passing on the
Web—here, you included our parameters for currency rate and amount as
part of the URL. Parameters start after the name of the page, MoreStuff.xaml, are prefixed by the "?" symbol, and are separated from each other by the "&" symbol.
Passing parameters is not enough in itself; an application must know how to properly process those parameters.
Open MoreStuff.xaml in the code view and add the following method to receive parameters and assign them to global variables:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string strExchgRate = "";
string strTotalToConvert = "";
if (NavigationContext.QueryString.TryGetValue("rate", out strExchgRate))
dblExchgRate = Convert.ToDouble(strExchgRate);
if (NavigationContext.QueryString.TryGetValue("total", out strTotalToConvert))
decTotalToConvert = Convert.ToDecimal(strTotalToConvert);
}
To make the foregoing code work, we must add the following two module-level variables to theMoreStuff.xaml.csde file:
Double dblExchgRate;
Decimal decTotalToConvert;
What's left is to add navigation to the other pages within the application.
Open MoreStuff.xaml in design view, double-click the Back to Main button, and make that button click event handler look like the following:
private void btnBackToMain_Click(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/MainPage.xaml",
UriKind.RelativeOrAbsolute));
}
Open Upgrade.xaml in Design view, double-click the Back to Main button, and make that button click event handler look like this:
private void btnGoBack_Click(object sender, RoutedEventArgs e)
{
NavigationService.GoBack();
}
Note the
different navigation implementation in this case: you are simply using
the code to go to the previous page within the application instead of
navigating to the specific page.
At this point, application
navigation is complete. You are ready to make sure that the trial
version of the application does not allow access to the "More Stuff"
page.