Saturday, December 24, 2011

UriMapping in Windows Phone 7

In this article we are discussing about UriMapping concept in Windows Phone 7. As your application grows you will probably have to use folders and perhaps subfolders in order to keep the project structure easy to follow.

The navigation system within a Windows Phone 7 application allows you to use UriMapping to convert a short URI into the full path of the XAML page within your project. UriMapping is a mechanism; that allows us to implement developer friendly navigation between Windows Phone 7 applications.

What is UriMapping?

UriMapping is an alias of physical path of views in WP7 project, which allows developer to mapped entire views using UriMapper class object. It helps developer to modify the project structure and without making any changes in the navigation code.

To developer friendly term, Uri-Mapping mechanism is used to hide the actual (physical of a file path) navigation structure of application and it also provides easy way to pass data through parameters to the pages by using query string between one page to another page.

Let’s take an example for the same; in this case we have created three xaml pages like (Facebook.xaml, PramValues.xaml, Twitter.xaml).

In this project structure we have one UI directory to keep all views. See below picture.


There are some basic steps to achieve this functionality in the project.

Step-1: Create an instance of UriMapper class object in App.xaml.cs class and add URI mapping items in Constructor for the Application object. And now add UriMapper object to PhoneApplicationFrame’s object RootFrame’s property UriMapper. See below code snippet for the same.

public App()
// Global handler for uncaught exceptions. 
       UnhandledException += Application_UnhandledException;
       // Standard Silverlight initialization
       // Phone-specific initialization
// URI Mapping 
var appNavigationMapper = new UriMapper();
appNavigationMapper.UriMappings.Add(CreateUriMapping("Twitter", "/UIs/Twitter.xaml"));
appNavigationMapper.UriMappings.Add(CreateUriMapping("About/{value}/{value1}", "/UIs/PramValues.xaml?id={value}&name={value1}"));
RootFrame.UriMapper = appNavigationMapper;
// Show graphics profiling information while debugging.
if (System.Diagnostics.Debugger.IsAttached)
// Display the current frame rate counters.
Application.Current.Host.Settings.EnableFrameRateCounter = true;
// Show the areas of the app that are being redrawn in each frame.
//Application.Current.Host.Settings.EnableRedrawRegions = true;
// Enable non-production analysis visualization mode, 
// which shows areas of a page that are handed off to GPU with a colored overlay.
//Application.Current.Host.Settings.EnableCacheVisualization = true;
// Disable the application idle detection by setting the UserIdleDetectionMode property of the
// application's PhoneApplicationService object to Disabled.
// Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
// and consume battery power when the user is not using the phone.
PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;

Step-2: Now we are developing UI (user interface) for accessing the particular UI using UriMapping mechanism. In this example I have added three buttons for like Twitter, Facebook and Param(s) to call the specific UI with an action of appropriate command button. Here is UI design with xaml code.

<Grid x:Name="LayoutRoot" Background="Transparent">
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="Uri Mapper" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Button Content="Twitter" Height="72" HorizontalAlignment="Left" Margin="40,68,0,0" Name="button1" VerticalAlignment="Top" Width="160" Click="button1_Click" Background="#FFEB3636"></Button>
            <Button Content="Facebook" Height="72" HorizontalAlignment="Left" Margin="240,209,0,0" Name="button2" VerticalAlignment="Top" Width="160" Click="button2_Click" Background="#FFEB3636"></Button>
            <Button Content="Param(s)" Height="72" HorizontalAlignment="Left" Margin="42,365,0,0" Name="button3" VerticalAlignment="Top" Width="160" Click="button3_Click" Background="#FFEB3636" />

Step-3: At the end we will call the URI mapping using NavigationService.Navigate() method. In this example I have created a generic method for calling specific UI call by specific alias of UriMapping name as we mentioned in the App.xaml.cs class constructor. See below code snippet.

private void DoNavigate(string NavigatePageName)
    this.NavigationService.Navigate(new Uri(NavigatePageName, UriKind.Relative));
private void button1_Click(object sender, RoutedEventArgs e)
private void button2_Click(object sender, RoutedEventArgs e)
private void button3_Click(object sender, RoutedEventArgs e)
     DoNavigate("About/2/pavan"); // With two parameters

The Following code shows an example of Uri mapping process. When user pass “About/2/pavan” it will be navigated to relative address “/About/2/pavan” which is a fake address. That fake address is mapped by “About/{value}/{value1}” to “/UIs/PramValues.xaml?id={value}&name={value1}”

How to get Query string values in Navigated Page.

Using NavigationContext is used to retrieve the specific value about the passing by the parameters. See below code for the same.

void PramValues_Loaded(object sender, RoutedEventArgs e)
   // Method - 1
   textBlock1.Text = string.Format("Id= {0}", NavigationContext.QueryString["id"]);
   textBlock2.Text = string.Format("Name= {0}",NavigationContext.QueryString["name"]);
   // Method - 2
   var values = NavigationContext.QueryString.ToArray();
   foreach (var item in values)
      System.Diagnostics.Debug.WriteLine("Key : " + item.Key + "  " + "Value : " + item.Value);

Step-4: Press F5 to execute the application.

~ Happy Coding Smile

Source Code

No comments: