Silverlight for Windows Phone Programming Tip – Navigation

When using the Silverlight for Windows Phone APIs to navigate from one page to another, it is necessary to use the Navigate method on the PhoneApplicationPage instance’s NavigationService property.  When making this call, it is important to note the required Uri Syntax, as follows:

Navigating to a page in the same assembly:

NavigationService.Navigate(new Uri("/Folder(s)/TargetPage.xaml", UriKind.relative));

Navigating to a page in another assembly:

NavigationService.Navigate(new Uri("/AssemblyName;component/Folder(s)/TargetPage.xaml", UriKind.Relative));

The current MSDN Documentation (update date of 1/28/2001) for the Navigate method does not include any text that specifies the requirements for the syntax or the Uri, so here goes my attempt to provide the missing content:

  • The provided Uri must start with a forward slash (/), indicating the content is local to the Xap file.  Failure to include the leading slash will result in an ArgumentException (details below) being thrown.
  • The UriKind must be specified as UriKind.Relative (or URIKindRelativeOrAbsolute, but why ask for trouble?)  Omitting the UriKind uses the default value of URIKind.Absolute, which yields the same ArgumentException
  • To navigate to a page in another assembly contained within the same Xap file, the syntax must include the Assembly Name for the assembly that contains the page, then a semicolon and the word “component”, followed by the folder path to the page.
    • The leading slash and the specification of a Relative Uri are still required, with the same consequences if omitted.
    • Omitting the word “component” results in an InvalidOperationException (No Xaml was found at the location…)

The description contained in the Argument exception is actually quite helpful – it reads “Navigation is only supported to relative URIs that are fragments, or begin with ‘/’, or which contain ‘;component.”  However, you have to first fail in your attempts to navigate and be in a position to trap and analyze the exception for it to be useful.

Making small and subtle mistakes in the navigation Uri is quite easy to do…not only is missing relevant documentation missing as noted above, but this API also falls quite short in the “Pit of Success” category at the expense of matching up with the Navigation API in regular Silverlight (I have witnessed good presenters’ phone demos get derailed and lose precious time because of some simple omissions in this regard.)  A better alternative would have been to have offered a way to avoid the specific nuances of the API in favor of phone-specific methods.  (Jeremy’s Ultra-Light Windows Phone 7 MVVM Framework accomplishes something very close/similar.)  Fortunately, if you are doing a lot of navigation in your app and would like to include a set of phone-specific NavigateToPhonePage calls which figure out and correct the necessary Uris for you, there is a quick way to do so – using Extension Methods.  A set of simple & helpful starter Phone Navigation extension methods follows:

public static class PhoneNavigationServiceExtensions
{     
      public static void NavigateToPhonePage(this NavigationService navigationService, String page)     
      {          
           if (navigationService == null) throw new ArgumentNullException("navigationService");          
           if (!page.StartsWith("/")) page = "/" + page;  //Compensate for lack of leading slash          
           navigationService.Navigate(new Uri(page, UriKind.Relative)); //Build the Uri, force it to be Relative.
      }

      public static void NavigateToLocalPhonePage(this NavigationService navigationService, String page)
      {
           NavigateToPhonePage(navigationService, page);
      }     

      public static void NavigateToExternalPhonePage(this NavigationService navigationService, String assemblyName, String page)     
      {          
           if (!page.StartsWith("/")) page = "/" + page;  //Compensate for lack of leading slash in the page          
           NavigateToPhonePage(navigationService, String.Format("{0};component{1}", assemblyName, page));     
      }
}

Given these extensions, the following navigation calls all work without a need to specify the UriKind, and with varying inclusions and omissions of the forward slashes:

// Using NavigateToLocalPhonePage requires nothing more than the path to the page's xaml file
NavigationService.NavigateToLocalPhonePage("/Folder(s)/TargetPage.xaml");
NavigationService.NavigateToLocalPhonePage("Folder(s)/TargetPage.xaml");

// Using NavigateToExternalPhonePage calls out the need for the assembly name and the page's xaml file path
NavigationService.NavigateToExternalPhonePage("/WindowsPhoneClassLibrary1", "/Folder(s)/TargetPage.xaml");
NavigationService.NavigateToExternalPhonePage("WindowsPhoneClassLibrary1", "Folder(s)/TargetPage.xaml");

// Using the NavigateToPage method directly works for either, but the External page must be specified correctly
NavigationService.NavigateToPhonePage("Folder(s)/TargetPage.xaml");
NavigationService.NavigateToPhonePage("WindowsPhoneClassLibrary1;component/Folder(s)/TargetPage.xaml");

Tech Valley .Net User Group Presentation Materials

I have uploaded the content from my Introduction to Windows Phone 7 Development with Silverlight talk at the Tech Valley .Net User Group meeting last night in Albany. The content can be found here, and includes:

  • Presentation slides, which include the reference links I mentioned during the talk.
  • The sample code, broken into 2 projects. Because the Notification Services portion of the talk adds extra projects to the solution ad is a little more complex to build and launch, that portion has been broken out into its own separate zip file.

For the Notification Services portion of the demo, the web project should be launched first, followed by the phone project (since the phone app calls the web site to register its URL for receiving notifications.) If the solution is run with the web project set as the default start project, the application bits do get deployed to the phone, but the debugger is not hooked up (unless multiple startup projects are used.) If debugging of the phone app is desired, it can be achieved by right clicking on the phone project and selecting Debug / Start New Instance. Also, this time the Notification Services demo includes the Push Notification Server-Side Helper recipe.

As usual, I have “sanitized” the uploaded code content by removing my personal Bing Maps application key. For information on how to obtain your own map key, please check out the Bing Maps Developer Portal.

Silverlight for Windows Phone Programming Tip – Be Sure to Scope Your SIP

Scope Your SIP – sounds painful, doesn’t it? Adding on to Jeff‘s series concerning WP7 Silverlight development tips, I figured it worthwhile to add another one. The SIP is the Software Input Panel – AKA the Phone’s onscreen keyboard. One of the handy features of the SIP is the ability to customize it to fit the needs of the textbox it is being displayed for – eg if you need to enter a phone number, why wrestle with a bunch of letter keys?
Figure 1- SIP default appearance (USA)
To do so, it is necessary to provide set the TextBox’s InputScope property to one of the values in the InputScopeNameValue enumeration, as pictured below:
<TextBox>
    <TextBox.InputScope>
        <InputScope>
            <InputScopeName NameValue="TelephoneNumber"/>
        </InputScope>
    </TextBox.InputScope>
</TextBox>
																			
Figure 2- SIP with TelephoneNumber Selected for the InputScope
Note that this is a little convoluted than the original description, which perhaps should have stated “it is necessary to provide the TextBox’s InputScope property with an InputScope object which contains the desired input scope name.” InputScope actually accepts a list of Names, of which only the first currently has any effect on the SIP display.
public sealed class InputScope : DependencyObject
{
    public InputScope();    
    public IList Names { get; }
}
If you want suggested word completions to appear as the user types letters, the only InputScope values that currently support completion are “Text” and “Chat.”
<TextBox>
    <TextBox.InputScope>
        <InputScope>
            <InputScopeName NameValue="Text"/>
        </InputScope>
    </TextBox.InputScope>
</TextBox>
																			
Figure 3- Showing Word Completion Suggestions with “Text” InputScope Selected

The New Phone Tools [are] Here! The New Phone Tools [are] Here!

With all due respect to Steve Martin’s hilarious portrayal of Navin R. Johnson and his quest for “his special purpose” in 1979′s The Jerk. Tonight Microsoft released the Windows Phone Developer Tools January 2011 Update, which can be downloaded here. In addition to the content in the new tools, there’s also some interesting other news concerning the availability of unsubsidized phones for purchase at Zones.com.

The New Tools

The big update item is the addition of Copy & Paste functionality. All TextBox and PasswordBox controls now get Copy and Paste functionality. This apparently applies to applications already in the Marketplace – once the update has been applied to the phone, Copy & Paste is available. The new behavior is bi-directionally compatible…controls within apps already on phones will automatically get Copy & Paste when the phone is upgraded, and apps compiled against the new Developer Tools will not misbehave on phones that have not yet received the update.

Note – the update is only for the developer tools – it is not yet available to be applied to devices – unlocked developer devices or otherwise. It only works in the Emulator.

Looking at the Copy & Paste behavior, when a TextBox has focus and a word is tapped, it gets a special highlight and the Copy Button appears. This works both with the mouse clicking in the emulator, as well as using touch when testing on a touch-enabled PC. There is no option for selecting portions of a word (eg to just select the “op” in the word “Copy”.) That last caveat is probably not that big of a deal, as selecting portions of a word on a touch device the size of a phone probably requires too much finesse. Multiple words can be selected – which is discussed below.

Figure 1- Selecting a Word and Displaying the Copy Button

To select multiple words, once the first word has been selected, it pressing and dragging on either edge allows the amount of text to be copied (in full word increments) to be adjusted

Figure 2- Extending the Selection to Multiple Words

Once text has been copied, a special Paste Button appears over the top of the onscreen keyboard (AKA Software Input Panel or SIP.) This is the same area where type-ahead suggestions appear.

Figure 3- The Paste Button on the Standard (US) SIP

Figure 4- The Paste Button on the SIP with InputScope Set to “TelephoneNumber”

In addition to TextBox and PasswordBox controls, the Copy & Paste functionality extends to controls that internally make use of TextBox controls, such as the Silverlight for Windows Phone Toolkit implementation of the AutoComplete Box. It also works for Text Input controls in web pages displayed in the WebBrowser control or in the phone’s Web Browser. However, in the WebBrowser control, the Copy Button can tend to “wander” a little bit…

Figure 5- Copy & Paste Controls in the Web Browser Control. Note the Odd Copy Button Placement

Paste is fairly straightforward. Select any control where the SIP appears and select the Paste Button. Paste is “single-shot” – there does not appear to be multiple Paste. Once the Paste Button has been pressed, the “clipboard” content is pasted into the target location, and the Paste Button is removed.

Two more quick notes about Copy & Paste:

  1. The “clipboard” persists outside of the application, so copied text can be used in other phone applications (for example, copying a Url from an application and pasting it into the browser’s address bar.) This also includes Tombstoning.
  2. The update also includes updates to the Pivot and Panorama controls. The update is for when TextBox controls have been added to panels within these controls, and aims to suppress inadvertent swipes when trying to copy text. Apps that have TextBoxes in Pivot or Panorama controls will need to be recompiled to get this change (they will still have Copy & Paste, though there may be some usability issues…)
    1. (Yes, the issue Jeff saw with Tombstoning is still there…)

Other Stuff in the New Tools

Other than the Copy & Paste feature, there are a couple of other things included with the update:

  • The Bing Maps Control has been updated for better gesture responsiveness
  • The update includes the Windows Phone Connect Tool, which is installed at <x86_ProgramFilesDir>\Microsoft SDKs\Windows Phone\v7.0\Tools\WPConnect. This tool can be used to connect a device for debugging when Zune is not running, which is necessary when debugging apps that use the media APIs.
  • The update includes the Windows Phone Capability Detection Tool, which is installed at <x86_ProgramFilesDir>\Microsoft SDKs\Windows Phone\v7.0\Tools\CapDetect. This tool is equivalent to the one used when applications are submitted to the Marketplace to inspect the app’s code so as to determine which capabilities are required by the app. These values are then used to replace the list in the app manifest. This tool can be used to preview what capabilities will be being detected before the app is submitted, in order to prevent issues like one (of admittedly several) issues seen by Shawn Wildermuth (see “Problem Part 4″) when an assembly that was inadvertently left in the application caused the app to report capabilities it actually didn’t need.

In addition to the tools, there is also a separate bug fix (VS10-KB2486994-x86.exe) that addresses a bug that existed whereby XAP files over 64MB could not be deployed by developers to physical devices for testing.

Issues with the Update

There is one known (at this time) defect with the update. Installing the update sets the default target for debugging Windows Phone Applications to be the “Windows Phone 7 Device”, even when a device is not installed. It is easy enough to change the value when Visual Studio barks at you, but it doesn’t “remember” the change, so it gets really old really fast.

Figure 6- The Default Debug Target for Phone Apps Changed to Windows Phone 7 Device

According to the Release Notes, the following steps are necessary in order to change this behavior (they work!)

  1. Close all Visual Studio and Windows Phone Emulator instances.
  2. Delete the contents of %LocalAppData%\Microsoft\Phone Tools\CoreCon.
  3. Restart Visual Studio.

Purchasing Unsubsidized Phones

In addition to publishing these new tools, apparently Microsoft has entered into a partnership with zones.com to allow the purchase of WP7 phones without going through one of the wireless carriers and the associated contract. The phones are locked to a specific carrier (it is not possible to take the Samsung Focus to T-Mobile in the US, for example), but they do allow developers to obtain devices for testing. As of the time of this writing, there is mention on the site of a “coupon code” which can be applied for some kind of discount, but I have no other information about any such offers. There are currently 3 phones available for purchase – the AT&T-offered HTC Surround ($500) and Samsung Focus ($525), and the T-Mobile HTC HD7 ($500). The zones.com developer purchase portal can be found at http://www.zones.com/windowsphonedeveloperpurchase.