Exercise 1: Introduction to the Windows Phone Launchers

In this exercise, you open the starter solution and complete the following tasks:

  • Add and navigate to multiple pages
  • Explore a different launcher on each page

The starting point for this exercise is the solution located in the lab installation folder under the Source\Begin folder.

Task 1 – Using Launchers

A launcher is an API that launches one of the built-in applications through which a user completes a task and in which no data is returned to the calling application. An example of this is the PhoneCallTask. An application can provide this launcher with a phone number and a display name with which to invoke the phone. When the phone application is displayed, the user can select whether to initiate a call using the supplied parameters. When the user closes the phone application, the calling application is usually activated again, but the phone application does not return any data about or resulting from the user’s actions. When an application invokes a launcher, it does not get a return value.

  1. Open SavePhoneNumberPage.xaml.cs.
  2. Add the following code to the SavePhoneNumberPage class:

    C#

    //Regex patterns provided by https://regexlib.com/ const string phoneNumberPattern = @"^([0-9]( |-)?)?(\(?[0-9]{3}\)?|[0-9]{3})( |-)?([0-9]{3}( |-)?[0-9]{4}|[a-zA-Z0-9]{7})$";

  3. Add the following using statements:

    C#

    using System.Text.RegularExpressions; using Microsoft.Phone.Tasks; using System.Diagnostics; using System.Windows.Navigation;

  4. Override the OnNavigatedFrom and OnNavigatedTo functions in order to save the phone number into the page's state so it can be displayed again in case the application is tombstoned.

    C#

    protected override void OnNavigatedFrom(NavigationEventArgs e) { Debug.WriteLine("***\t In OnNavigatedFrom function of SavePhoneNumberPage\t ***"); if (State.ContainsKey(inputStateKey)) State.Remove(inputStateKey); State.Add(inputStateKey, txtInput.Text); base.OnNavigatedFrom(e); } protected override void OnNavigatedTo(NavigationEventArgs e) { Debug.WriteLine("***\t In OnNavigatedTo function of SavePhoneNumberPage\t ***"); if (State.ContainsKey(inputStateKey)) { string input = (string)State[inputStateKey]; txtInput.Text = input; State.Remove(inputStateKey); } base.OnNavigatedTo(e); }

  5. Add the input state key constant to the SavePhoneNumberPage class.

    C#

    const string inputStateKey = "input";

  6. Add a SavePhoneNumberTask variable to the SavePhoneNumberPage class.

    C#

    SavePhoneNumberTask savePhoneNumberTask;

  7. Add the following highlighted code to initialize the savePhoneNumberTask variable in the class constructor and output debug information.

    C#

    public SavePhoneNumberPage() { InitializeComponent(); Debug.WriteLine("***\t In constructor of SavePhoneNumberPage\t ***"); savePhoneNumberTask = new SavePhoneNumberTask(); savePhoneNumberTask.Completed += new EventHandler<TaskEventArgs>(savePhoneNumberTask_Completed); }

  8. Add the handler function for the completion event.

    C#

    void savePhoneNumberTask_Completed(object sender, TaskEventArgs e) { Debug.WriteLine("***\t In savePhoneNumberTask_Completed function of SavePhoneNumberPage\t ***"); if (e.TaskResult == TaskResult.OK) MessageBox.Show("Phone number saved successfully", "Success", MessageBoxButton.OK); else if (e.TaskResult == TaskResult.Cancel) MessageBox.Show("Phone number was not saved - operation was cancelled", "Contact not selected", MessageBoxButton.OK); else MessageBox.Show("Error while saving phone number:\n" + e.Error.Message, "Fail", MessageBoxButton.OK); }

  9. Use the regular expression to validate user input. If input passes validation, use the SavePhoneNumberTask to save the validated phone number. SavePhoneNumberTask enables an application to launch the contacts application. Use this to allow users to save a phone number from the calling application to a new or existing contact.

    C#

    private void btnSavePhone_Click(object sender, RoutedEventArgs e) { if (Regex.IsMatch(txtInput.Text, phoneNumberPattern, RegexOptions.IgnoreCase)) { if (null != savePhoneNumberTask) { savePhoneNumberTask.PhoneNumber = txtInput.Text; savePhoneNumberTask.Show(); } } else { MessageBox.Show("Specified value is not a valid phone number\nValid phone number looks like the following:\n1-(123)-123-1234, 123 123 1234, 1-800-ALPHNUM", "Invalid Input", MessageBoxButton.OK); } }

  10. Press F5 to compile and run the application.
  11. Navigate to the Save Phone Number page and type a valid phone number.
  12. To execute the Launcher click Save Phone Number.
  13. Add the phone number to a new or existing contact using the standard Windows® Phone 7 interface:

    Figure 1

    Adding a phone number to existing or new contact

  14. Optionally, give the contact a name.
  15. Save the contact and click Back ():

    Figure 2

    Launcher return notification

    Note:
    Note: The inserted phone number should appear in the input text box even though the application was sent to the background during the PhoneSaveTask operation. Analyze the debug output to gain a better understanding of this process.

  16. Repeat this step to add a new contact.

    Note:
    Note: The emulator preserves contacts data only when it is running. Please do not close the emulator between the steps. This enables viewing the contact’s information later on in the lab.

  17. Press SHIFT+F5 to stop the debugger and return to editing mode.
  18. Open SaveEmailAddressPage.xaml.cs.
  19. Note we overrode the OnNavigatedFrom and OnNavigatedTo functions in order to save the email address into the page's state so it can be displayed again in case the application has been tombstoned .
  20. Add a SaveEmailAddressTask variable to the SaveEmailAddressPage class.

    C#

    SaveEmailAddressTask saveEmailAddressTask;

  21. Add the following highlighted code to initialize the saveEmailAddressTask variable in the class constructor.

    C#

    public SaveEmailAddressPage() { InitializeComponent(); Debug.WriteLine("***\t In constructor of SaveEmailAddressPage\t ***"); saveEmailAddressTask = new SaveEmailAddressTask(); saveEmailAddressTask.Completed += new EventHandler<TaskEventArgs>(saveEmailAddressTask_Completed); }

  22. Replace the handler function for the completion event.

    C#

    void saveEmailAddressTask_Completed(object sender, TaskEventArgs e) { Debug.WriteLine("***\t In saveEmailAddressTask_Completed function of SaveEmailAddressPage\t ***"); if (e.TaskResult == TaskResult.OK) MessageBox.Show("Email address saved successfully", "Success", MessageBoxButton.OK); else if (e.TaskResult == TaskResult.Cancel) MessageBox.Show("Email address was not saved - operation was cancelled", "Contact not selected", MessageBoxButton.OK); else MessageBox.Show("Error while saving email address:\n" + e.Error.Message, "Fail", MessageBoxButton.OK); }

  23. Use the regular expression to validate user input. If input passes validation, use the SaveEmailAddressTask to save the validated email address. SaveEmailAddressTask enables an application to launch the contacts application. Use this to allow users to save an email address from within the calling application to a new or existing contact.

    C#

    private void btnSaveEmail_Click(object sender, RoutedEventArgs e)
    FakePre-0076646eae6341e289b3e0cfaf9d7c83-6fc53d0dfbfb4553b9973b3542c02063FakePre-136d8dba450e4d1bb965a9e6ea35c442-46f60d92964a4c8ab304ab3845c64540FakePre-f449a21372df4f8ab2c88b2a40556886-302e6ac58897448d81e0f0ce716df3dcFakePre-5c93b6b7cfbc464ab1a279f15b204a9e-3626474fc1614583905c38ca52c8fb57FakePre-61e437b433a44baeb8fcab14a07e12dc-8b3db79c99964bd7bb54ffa9039a3551FakePre-e75b3355776b4e65934df1292cfe9e6e-e1f72008f85b4a31be637eded042844bFakePre-2dc88f94d4e949f29c51eb125dfa75a4-49e272e7ba7b446899b70e72935abe51FakePre-623556b4fe024878b94f580efd40a3bf-ec4b701363c7459ea02b6c859acade66FakePre-b4df750a4d6c4ca2a2d87051baf0bdf0-1d346e0dcd8f455b89bcf15b3a735fc3FakePre-bdef8f1771344de0a1d8e1c970dd0806-f534fae457fe4a8c941c0c84ff821e45FakePre-1db50d19f78c4faa8baebf6d80cbb96f-c110f1a1fc2a4a7bb6486ba4c101b224FakePre-562db49b9cd7467d880e48d71dd21c74-166bf49bf1fb45f7a604b5a993f62af6FakePre-cdd8ca0ccbca4812abc1d8ee47cb64bd-9ab53b526d164bf4802f20df8b24cf29 }

  24. Press F5 to compile and run the application.
  25. Navigate to the Save Email page and type a valid email address.
  26. To execute the Launcher, click Save Email Address.
  27. Add the email address to a new or existing contact using the standard Windows® Phone 7 interface:

    Figure 3

    Adding an email address to existing or new contact

  28. Save the contact and click Back ():
  29. Press SHIFT+F5 to stop the debugger and return to editing mode.
  30. Open SearchTaskPage.xaml.cs.
  31. Note we overrode the OnNavigatedFrom and OnNavigatedTo functions in order to save the search term into the page's state so it can be displayed again in case the application has been tombstoned:
  32. To execute the search functionality this lab uses SearchTask. SearchTask enables an application to launch the Web Search application. Locate the btnSearch_Click event handler function and add the following code to the function body:

    C#

    private void btnSearch_Click(object sender, RoutedEventArgs e) { SearchTask searchTask = new SearchTask(); searchTask.SearchQuery = txtInput.Text; searchTask.Show(); }

  33. Compile and run the application.
  34. Navigate to the Search page and input a search query:

    Figure 4

    Search Page

  35. Click Search Everywhere.
  36. It is possible, that the first search execution displays a screen asking to allow location information usage. Click Allow.
  37. The emulator connects to the Web and brings back the defined query results:

    Figure 5

    Web Results

  38. Press SHIFT+F5 to stop the debugging and return to editing mode in Visual Studio.
  39. Open WebSearchPage.xaml.cs.
  40. Note we overrode the OnNavigatedFrom and OnNavigatedTo functions in order to save the search term into the page's state so it can be displayed again in case the application has been tombstoned.
  41. Silverlight has a WebBrowser control that could be used as any other Silverlight control in the application. In addition Windows Phone has a WebBrowser launcher enabling Internet Explorer to be started directly from the application. To use it, this lab uses WebBrowserTask.WebBrowserTask enables an application to launch the Web browser application. Locate the btnGo_Click event handler function and add the following code to the function body:

    C#

    private void btnGo_Click(object sender, RoutedEventArgs e) { WebBrowserTask webBrowserTask = new WebBrowserTask(); const string url = "https://m.bing.com/search?q={0}&a=results"; webBrowserTask.URL = string.Format(url, txtInput.Text); webBrowserTask.Show(); }

  42. Press F5 to compile and run the application.
  43. Navigate to the Search with Bing page and input a search query.
  44. The Launcher starts Internet Explorer and navigates to Bing web page:

    Figure 6

    Windows® Phone 7.1 IE

  45. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.
  46. Open VideoPlayerPage.xaml.cs.
  47. Override the OnNavigatedFrom and OnNavigatedTo functions in order to add debug information when the application is being tombstoned.

    C#

    protected override void OnNavigatedFrom(NavigationEventArgs e) { Debug.WriteLine("***\t In OnNavigatedFrom function of VideoPlayerPage\t ***"); base.OnNavigatedFrom(e); } protected override void OnNavigatedTo(NavigationEventArgs e) { Debug.WriteLine("***\t In OnNavigatedTo function of VideoPlayerPage\t ***"); base.OnNavigatedTo(e); }

  48. From the Source\Assets folder of this lab, add an existing video file to the project’s Media folder.
  49. At the Add Existing Item dialog browse to the Assets folder of this lab, select the video file, and from the Add button drop down list select Add As Link.

    Figure 7

    Selecting the video file

  50. Make sure the video file was added as a Content resource. To check it, click on the added file in Solution Explorer and press F4 to show the file properties.

    Figure 8

    Checking the Build Action of the added video file

  51. Add an event handler function to handle the button click event. The function will use the MediaPlayerLauncher which allows an application to launch the media player to play a video file. Add the following code to the class:

    C#

    private void btnPlayVideo_Click(object sender, RoutedEventArgs e) { MediaPlayerLauncher mediaPlayerLauncher = new MediaPlayerLauncher(); mediaPlayerLauncher.Location = MediaLocationType.Install; //means is a resource of the app, otherwise it will try to resolve it in Data (IsolatedStorage) for application mediaPlayerLauncher.Media = new Uri("Media/Bear.wmv", UriKind.Relative); mediaPlayerLauncher.Show(); }

  52. Press F5 to compile and run the application.
  53. Navigate to the Video Player page and play the video.
  54. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.
  55. Open SaveRingtonePage.xaml.cs.
  56. Add the following using statements to the class:

    C#

    using System.IO.IsolatedStorage; using System.IO;

  57. Note we overrode the OnNavigatedFrom and OnNavigatedTo functions in order to supply debug information when the application is tombstoned.
  58. Add a sound file that will serve as a ringtone to the project. Perform steps 48-50 inclusive a second time, but instead of adding “Bear.wmv” add “Ring.mp3”.
  59. Add the following highlighted code to create the debug information in the class constructor, and to deploy the sound file that we will use as the new ringtone to isolated storage.

    C#

    public SaveRingtonePage() { InitializeComponent(); Debug.WriteLine("***\t In constructor of SaveRingtonePage\t ***"); PlaceAssetInIsolatedStorage(); }

  60. Add the following additional methods for storing the ringtone in isolated storage:

    C#

    private static void PlaceAssetInIsolatedStorage() { using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication()) { Stream str = Application.GetResourceStream(new Uri("Media/Ring.mp3", UriKind.Relative)).Stream; IsolatedStorageFileStream outFile = iso.CreateFile("Ring.mp3"); outFile.Write(ReadToEnd(str), 0, (int)str.Length); str.Close(); outFile.Close(); } } private static byte[] ReadToEnd(System.IO.Stream stream) { long originalPosition = stream.Position; stream.Position = 0; try { byte[] readBuffer = new byte[4096]; int totalBytesRead = 0; int bytesRead; while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0) { totalBytesRead += bytesRead; if (totalBytesRead == readBuffer.Length) { int nextByte = stream.ReadByte(); if (nextByte != -1) { byte[] temp = new byte[readBuffer.Length * 2]; Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length); Buffer.SetByte(temp, totalBytesRead, (byte)nextByte); readBuffer = temp; totalBytesRead++; } } } byte[] buffer = readBuffer; if (readBuffer.Length != totalBytesRead) { buffer = new byte[totalBytesRead]; Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead); } return buffer; } finally { stream.Position = originalPosition; } }

  61. To allow the user to associate a ringtone with a contact, we will use the SaveRingtoneTask. Locate the btnSaveRingtone_Click event handler function and add the following code to the function body:

    C#

    private void btnSaveRingtone_Click(object sender, RoutedEventArgs e) { SaveRingtoneTask ringtoneTask = new SaveRingtoneTask(); ringtoneTask.Source = new Uri("isostore:/Ring.mp3", UriKind.Absolute); ringtoneTask.Show(); }

  62. Press F5 to compile and run the application.
  63. Navigate to the “Save Ringtone” page and press the screens only button: “Save Ringtone”
  64. It will take you to the phone’s built-in ringtone saving screen, allowing you to specify a filename for the saved ringtone and to set it as the active ringtone:

    Figure 9

    The built-in ringtone saving screen

  65. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.
  66. Open SaveContactPage.xaml.cs.
  67. Note we overrode the OnNavigatedFrom and OnNavigatedTo functions in order to add debug information when the application is being tombstoned.
  68. To allow the user to save information from application’s page into phone contacts, we will use the SaveContactTask. Locate the btnSaveContact_Click event handler function and add the following code to the function body (continue the “if” statement provided by starter solution):

    C#

    else { SaveContactTasksaveContactTask =newSaveContactTask(); saveContactTask.Company = txtCompany.Text; saveContactTask.FirstName = txtFirstName.Text; saveContactTask.LastName = txtLastName.Text; saveContactTask.JobTitle = txtJobTitle.Text; saveContactTask.WorkEmail = txtWorkEmail.Text; saveContactTask.Website = txtWebsite.Text; saveContactTask.Nickname = txtNickname.Text; saveContactTask.Completed += (s, args) => { if(null== args.Error) { MessageBox.Show(string.Format("Contact {0}saved!", (args.TaskResult ==TaskResult.Cancel ?"not ":""))); } else MessageBox.Show("Error saving contact!"); }; saveContactTask.Show(); }

  69. Press F5 to compile and run the application.

    Figure 10

    Saving contact information

  70. Navigate to the Save New Contact page, provide required information and click “Save New Contact” button. Save the new contact and click Back ().
  71. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.
  72. Open ComposeEmailPage.xaml.cs.
  73. Use the following code to place an additional class in the file. We will use this class to store input data provided by the user:

    C#

    public class EmailInputData { public string To { get; set; } public string Cc { get; set; } public string Bcc { get; set; } public string Subject { get; set; } public string Body { get; set; } }

  74. Override the OnNavigatedFrom and OnNavigatedTo functions in order to save the email data into the page's state so it can be displayed again in case the application has been tombstoned.

    C#

    protected override void OnNavigatedFrom(NavigationEventArgs e) { Debug.WriteLine("***\t In OnNavigatedFrom function of ComposeEmailPage\t ***"); if (State.ContainsKey(inputStateKey)) State.Remove(inputStateKey); EmailInputData inputData = new EmailInputData { To = txtTo.Text, Cc = txtCc.Text, Bcc = txtBcc.Text, Subject = txtSubject.Text, Body = txtBody.Text }; State.Add(inputStateKey, inputData); base.OnNavigatedFrom(e); } protected override void OnNavigatedTo(NavigationEventArgs e) { Debug.WriteLine("***\t In OnNavigatedTo function of ComposeEmailPage\t ***"); if (State.ContainsKey(inputStateKey)) { EmailInputData inputData = (EmailInputData)State[inputStateKey]; txtTo.Text = inputData.To; txtCc.Text = inputData.Cc; txtBcc.Text = inputData.Bcc; txtSubject.Text = inputData.Subject; txtBody.Text = inputData.Body; State.Remove(inputStateKey); } base.OnNavigatedTo(e); }

  75. To allow the user to compose an email, we will use the EmailComposeTask. EmailComposeTask enables an application to launch the built in email composer, using data supplied by the user to initialize the email message composed. Locate the btnCreateEmail_Click event handler function and add the following code to the function body:

    C#

    private void btnCreateEmail_Click(object sender, RoutedEventArgs e) { if (Microsoft.Devices.Environment.DeviceType == Microsoft.Devices.DeviceType.Emulator) { MessageBox.Show("This operation is not supported in the emulator. Please use an actual device."); return; } EmailComposeTask composeTask = new EmailComposeTask(); composeTask.To = txtTo.Text; composeTask.Cc = txtCc.Text; composeTask.Bcc = txtBcc.Text; composeTask.Subject = txtSubject.Text; composeTask.Body = txtBody.Text; composeTask.Show(); }
    Note:
     Notice that we put code at the top of the handler method to prevent the task from being used on the Windows® Phone 7 emulator. We did this since the task cannot operate properly without setting an email account in the device and the emulator does not support setting up an email account.

    Be sure to set up an email account in your device for the next steps to work properly.

  76. Press F5 to compile and run the application.
  77. Navigate to the Compose Email page and fill out the desired fields:

    Figure 11

    Composing an email

  78. Pressing the “Create Email” button will take you to the phone’s built-in email composer, showing an email which contains the data supplied.
  79. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.
  80. Open ShowMapPage.xaml.cs.
  81. Use the following code to place an additional class in the file. We will use this class to store input data provided by the user:

    C#

    public class MapInputData { public bool CenterOnCoordinate { get; set; } public string Longitude { get; set; } public string Latitude { get; set; } public string Location { get; set; } public string ZoomLevel { get; set; } }

  82. Override the OnNavigatedFrom and OnNavigatedTo functions in order to save the map data into the page's state so it can be displayed again in case the application has been tombstoned.

    C#

    protected override void OnNavigatedFrom(NavigationEventArgs e) { Debug.WriteLine("***\t In OnNavigatedFrom function of ShowMapPage\t ***"); if (State.ContainsKey(inputStateKey)) State.Remove(inputStateKey); MapInputData inputData = new MapInputData { CenterOnCoordinate = radioCoordinate.IsChecked.Value, Longitude = txtLongitude.Text, Latitude = txtLatitude.Text, Location = txtLocation.Text, ZoomLevel = txtZoom.Text }; State.Add(inputStateKey, inputData); base.OnNavigatedFrom(e); } protected override void OnNavigatedTo(NavigationEventArgs e) { Debug.WriteLine("***\t In OnNavigatedTo function of ShowMapPage\t ***"); if (State.ContainsKey(inputStateKey)) { MapInputData inputData = (MapInputData)State[inputStateKey]; if (inputData.CenterOnCoordinate) { radioCoordinate.IsChecked = true; } else { radioLocation.IsChecked = true; } txtLocation.Text = inputData.Location; txtLatitude.Text = inputData.Latitude; txtLongitude.Text = inputData.Longitude; txtZoom.Text = inputData.ZoomLevel; State.Remove(inputStateKey); } base.OnNavigatedTo(e); }

  83. To allow the user to view the map, we will use the BingMapsTask. BingMapsTask enables an application to launch the built in maps application, using data supplied by the user to initialize the map’s position. Locate the btnShowMap_Click event handler function and add the following code to the function body:

    C#

    private void btnShowMap_Click(object sender, RoutedEventArgs e) { BingMapsTask mapTask = new BingMapsTask(); if (radioCoordinate.IsChecked.Value) { double longitude; double latitude; if (!double.TryParse(txtLongitude.Text, out longitude) || Math.Abs(longitude) > 180) { MessageBox.Show("Please supply a longitude between -180 and 180"); return; } if (!double.TryParse(txtLatitude.Text, out latitude) || Math.Abs(latitude) > 90) { MessageBox.Show("Please supply a longitude between -90 and 90"); return; } mapTask.Center = new GeoCoordinate(latitude, longitude); } else { mapTask.SearchTerm = txtLocation.Text; if (String.IsNullOrEmpty(mapTask.SearchTerm)) { MessageBox.Show("Please provide a location."); return; } } int zoomLevel; if (!int.TryParse(txtZoom.Text, out zoomLevel) || zoomLevel < 1 || zoomLevel > 19) { MessageBox.Show("Please supply a zoom level which is a whole number between 1 and 19."); return; } mapTask.ZoomLevel = zoomLevel; mapTask.Show(); }

  84. Press F5 to compile and run the application.
  85. Navigate to the Show Map page and select a location using a search term or a coordinate:

    Figure 12

    Selecting a map location

  86. Pressing the “Show Map” button will take you to the phone’s built-in maps application, centered at the designated location:

    Figure 13

    The map centered at the designated location

    Note:
     If you have not yet allowed the phone to use location information you may be prompted to do so now.

  87. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.
  88. Open DirectionsPage.xaml.cs.
  89. Use the following code to place an additional class in the file. We will use this class to store input data provided by the user:

    C#

    public class DirectionsInputData { public string Origin { get; set; } public string Destination { get; set; } }

  90. Override the OnNavigatedFrom and OnNavigatedTo functions in order to save the directions data into the page's state so it can be displayed again in case the application has been tombstoned.

    C#

    protected override void OnNavigatedFrom(NavigationEventArgs e) { Debug.WriteLine("***\t In OnNavigatedFrom function of DirectionsPage\t ***"); if (State.ContainsKey(inputStateKey)) State.Remove(inputStateKey); DirectionsInputData inputData = new DirectionsInputData { Origin = txtOrigin.Text, Destination = txtDestination.Text }; State.Add(inputStateKey, inputData); base.OnNavigatedFrom(e); } protected override void OnNavigatedTo(NavigationEventArgs e) { Debug.WriteLine("***\t In OnNavigatedTo function of DirectionsPage\t ***"); if (State.ContainsKey(inputStateKey)) { DirectionsInputData inputData = (DirectionsInputData)State[inputStateKey]; txtOrigin.Text = inputData.Origin; txtDestination.Text = inputData.Destination; State.Remove(inputStateKey); } base.OnNavigatedTo(e); }

  91. To allow the user to view directions, we will use the BingMapsDirectionsTask. BingMapsDirectionsTask enables an application to launch the built in maps application, using data supplied by the user to show directions between two locations. Locate the btnGetDirections_Click event handler function and add the following code to the function body:

    C#

    private void btnGetDirections_Click(object sender, RoutedEventArgs e) { BingMapsDirectionsTask directionsTask = new BingMapsDirectionsTask(); if (String.IsNullOrEmpty(txtOrigin.Text)) { MessageBox.Show("Please supply an origin."); return; } if (String.IsNullOrEmpty(txtDestination.Text)) { MessageBox.Show("Please supply a destination."); return; } directionsTask.Start = new LabeledMapLocation(txtOrigin.Text, null); directionsTask.End = new LabeledMapLocation(txtDestination.Text, null); directionsTask.Show(); }

  92. Press F5 to compile and run the application.
  93. Navigate to the Directions page and select two locations between which you wish to get directions:

    Figure 14

    Selecting origin and destination

  94. Pressing the “Get Directions” button will take you to the phone’s built-in maps application, showing the desired directions.
  95. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.
  96. Open ShareStatusPage.xaml.cs
  97. Note we overrode the OnNavigatedFrom and OnNavigatedTo functions in order to add debug information when the application is being tombstoned.
  98. To share user’s status, we will use ShareStatusTask. Locate the btnShareStatus_Click event handler and add the following code to the function body:

    C#

    if(txtStatus.Text.Length > 0) { ShareStatusTaskshareStatusTask =newShareStatusTask(); shareStatusTask.Status = txtStatus.Text; shareStatusTask.Show(); } else MessageBox.Show("Cannot share empty status.\nPlease enter your status and try again","Share Status - Error",MessageBoxButton.OK);

  99. Press F5 to compile and run the application.

    Note:
    Note: Status sharing functionality doesn’t works on emulator or if the device has no social accounts (Windows Live, Facebook, LinkedIn, Twitter) configured.

  100. Navigate to the Share Status page (in Social pivot page), provide new status and press the button to share it.
  101. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.
  102. Open ShareLinkPage.xaml.cs
  103. Note we overrode the OnNavigatedFrom and OnNavigatedTo functions in order to add debug information when the application is being tombstoned.
  104. To share link, we will use ShareLinkTask. Locate the btnSharelink_Click event handler and add the following code to the function body:

    C#

    if(txtLink.Text.Length > 0 &&Uri.IsWellFormedUriString(txtLink.Text,UriKind.Absolute)) { ShareLinkTaskshareLinkTask =newShareLinkTask(); shareLinkTask.Message = txtMessage.Text; shareLinkTask.Title = txtTitle.Text; shareLinkTask.LinkUri =newUri(txtLink.Text,UriKind.Absolute); shareLinkTask.Show(); } else MessageBox.Show("Cannot share link or link is invalid.\nPlease check your input and try again","Share Link - Error",MessageBoxButton.OK);

  105. Press F5 to compile and run the application.

    Note:
    Note: Status sharing functionality doesn’t work on emulator or if the device has no social accounts (Windows Live, Facebook, LinkedIn, Twitter) configured.

  106. Navigate to the Share Link page (in Social pivot page), provide new link and press the button to share it.
  107. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.
  108. Open ShowMarketplacePage.xaml.cs.
  109. Note we overrode the OnNavigatedFrom and OnNavigatedTo functions in order to add debug information when the application is being tombstoned.
  110. To allow the user to view the marketplace, we will use the MarketplaceHubTask. MarketplaceHubTask enables an application to launch the built in marketplace browser. Locate the btnShowMarketplace_Click event handler function and add the following code to the function body:

    C#

    private void btnShowMarketplace_Click(object sender, RoutedEventArgs e) { MarketplaceHubTask marketplaceTask = new MarketplaceHubTask(); marketplaceTask.Show(); }

  111. Press F5 to compile and run the application.
  112. Navigate to the Show marketplace page and press the button to go to the marketplace hub.
  113. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.
  114. Open ConnectionSettingsPage.xaml.cs
  115. Add the following code at the bottom of the page, before the end of namespace:

    C#

    public class ConnectionSettings { public string Name { get; set; } public ConnectionSettingsType TypeID { get; set; } }

  116. Now, add the following class-level variable which will be used as a source for page list box (at the top of ConnectionSettingsPage class):

    C#

    List<ConnectionSettings> connectionTypes;

  117. Add the list initialization code to the class:

    C#

    privatevoidInitializeConnectionTypes() { connectionTypes =newList<ConnectionSettings>(); connectionTypes.Add(newConnectionSettings() { TypeID =ConnectionSettingsType.AirplaneMode, Name ="Airplane Mode"}); connectionTypes.Add(newConnectionSettings() { TypeID =ConnectionSettingsType.Bluetooth, Name ="Bluetooth"}); connectionTypes.Add(newConnectionSettings() { TypeID =ConnectionSettingsType.Cellular, Name ="Cellular"}); connectionTypes.Add(newConnectionSettings() { TypeID =ConnectionSettingsType.WiFi, Name ="WiFi"}); lstConnectionTypes.DataContext = connectionTypes; lstConnectionTypes.SelectedIndex = 0; }

  118. Call the function created before from class constructor - add the following code line afterInitializeComponent() function:

    C#

    InitializeConnectionTypes();

  119. To allow the user to open system connection settings, we will use the ConnectionSettingsTask. ConnectionSettingsTask enables an application to launch the built in connection settings application, showing specific settings that matches defined settings type. Locate the btnConnectionSettings_Click event handler function and add the following code to the function body:

    C#

    ConnectionSettingsTaskconnectionSettingsTask =newConnectionSettingsTask(); connectionSettingsTask.ConnectionSettingsType = (lstConnectionTypes.SelectedItemasConnectionSettings).TypeID; connectionSettingsTask.Show();

  120. This code snippet defines which connection settings will be presented (defined by getting selection in the listbox) and starts the launcher.
  121. Press F5 to compile and run the application.
  122. Navigate to the Connection settings page at Settings hub, select connection settings type and press the button to go to the relevant system settings page.

    Figure 15

    Connection settings

  123. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.
  124. Open SearchMarketplacePage.xaml.cs.
  125. Note we overrode the OnNavigatedFrom and OnNavigatedTo functions in order to save the search term into the page's state so it can be displayed again in case the application has been tombstoned.
  126. To allow the user to search the marketplace, we will use the MarketplaceSearchTask. MarketplaceSearchTask enables an application to launch the built in marketplace application, showing only content that matches the search term. Locate the btnSearchMarketplace_Click event handler function and add the following code to the function body:

    C#

    private void btnSearchMarketplace_Click(object sender, RoutedEventArgs e) { MarketplaceSearchTask marketplaceTask = new MarketplaceSearchTask(); marketplaceTask.SearchTerms = txtSearchTerm.Text; marketplaceTask.Show();}

  127. Press F5 to compile and run the application.
  128. Navigate to the marketplace search page and enter a search term.
  129. Pressing the “Search Marketplace” button will launch the built-in marketplace application and search for content using the term provided:

    Figure 16

    Content matching the search term

  130. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.
  131. Open MarketplaceDetailsPage.xaml.cs.
  132. Note we overrode the OnNavigatedFrom and OnNavigatedTo functions in order to add debug information when the application is being tombstoned.
  133. To allow the user to view the details for a marketplace app, we will use the MarketplaceDetailTask. MarketplaceDetailTask enables an application to launch the built in marketplace application to display a specific app’s details. Locate the btnMarketplaceDetails_Click event handler function and add the following code to the function body:

    C#

    private void btnMarketplaceDetails_Click(object sender, RoutedEventArgs e) { MarketplaceDetailTask marketplaceTask = new MarketplaceDetailTask(); marketplaceTask.ContentIdentifier = "35323b0f-84d8-df11-a844-00237de2db9e"; marketplaceTask.Show(); }

  134. Press F5 to compile and run the application.
  135. Navigate to the marketplace details page and press the button to see the marketplace details for “The Harvest™”.

    Note:
    Marketplace and multimedia related actions do not work if the device is connected to a computer, even while debugging.

  136. Switch back to Visual Studio and press SHIFT+F5 to stop the debugger.

    This step concludes the exercise.

    Note:
    The solution for this exercise is located at this lab’s Source\End folder.