The SilverlightSimpleNavigation
project begins as usual with a MainPage
class, and as usual I set the two TextBlock
elements for the titles:
Example 1. Silverlight
Project: SilverlightSimpleNavigation File: MainPage.xaml (excerpt)
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="SIMPLE NAVIGATION" . . . /> <TextBlock x:Name="PageTitle" Text="main page" . . . /> </StackPanel>
|
The content area of MainPage.xaml contains only a TextBlock that sets a handler for its ManipulationStarted event:
Example 2. Silverlight
Project: SilverlightSimpleNavigation File: MainPage.xaml (excerpt)
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <TextBlock Text="Navigate to 2nd Page" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="0 34" ManipulationStarted="OnTextBlockManipulationStarted" /> </Grid>
|
Notice the Text
property on the TextBlock: “Navigate to
2nd page.” The code-behind file contains the handler for ManipulationStarted but also overrides the OnManipulationStarted method for the whole
page:
Example 3. Silverlight
Project: SilverlightSimpleNavigation File: MainPage.xaml.cs (excerpt)
public partial class MainPage : PhoneApplicationPage { Random rand = new Random();
public MainPage() { InitializeComponent(); }
void OnTextBlockManipulationStarted(object sender, ManipulationStartedEventArgs args) { this.NavigationService.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative));
args.Complete(); args.Handled = true; }
protected override void OnManipulationStarted(ManipulationStartedEventArgs args) { ContentPanel.Background = new SolidColorBrush( Color.FromArgb(255, (byte)rand.Next(255), (byte)rand.Next(255), (byte)rand.Next(255)));
base.OnManipulationStarted(args); } }
|
If you touch anywhere on the page
outside of the TextBlock, the
background of the ContentPanel is set
to a random color. Touch the TextBlock,
and the handler accesses the NavigationService property of the page. This is an object of type NavigationService
that contains properties, methods, and events related to navigation, including the crucial Navigate method:
this.NavigationService.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative));
The argument is an object of
type Uri. Notice
the slash in front of SecondPage.xaml, and notice the use of UriKind.Relative to
indicate a URI relative to MainPage.xaml.
I created a second page in the SilverlightSimpleNavigation
project by right-clicking the project name in the Visual Studio
solution explorer, and selecting Add and New Item. From the Add New Item dialog box, I picked Windows Phone Portrait Page
and gave it a name of SecondPage.xaml.
This process creates not only
SecondPage.xaml but also the code-behind file SecondPage.cs. The two
SecondPage files are virtually identical to the two MainPage files that
Visual Studio customarily creates. Like MainPage,
SecondPage derives from PhoneApplicationPage.
I gave the titles In
SecondPage.xaml the same application name as FirstPage.xaml but a page
title of “second page”:
Example 4. Silverlight
Project: SilverlightSimpleNavigation File: SecondPage.xaml (excerpt)
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="SIMPLE NAVIGATION" . . . /> <TextBlock x:Name="PageTitle" Text="second page" . . . /> </StackPanel>
|
The content area of
SecondPage.xaml is very much like MainPage.xaml but the TextBlock reads “Go Back
to 1st Page”:
Example 5. Silverlight
Project: SilverlightSimpleNavigation File: SecondPage.xaml (excerpt)
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <TextBlock Text="Go Back to 1st Page" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="0 34" ManipulationStarted="OnTextBlockManipulationStarted" /> </Grid>
|
The code-behind file of the SecondPage class is
also very much like the FirstPage
class:
Example 6. Silverlight
Project: SilverlightSimpleNavigation File: SecondPage.xaml.cs (excerpt)
public partial class SecondPage : PhoneApplicationPage { Random rand = new Random();
public SecondPage() { InitializeComponent(); }
void OnTextBlockManipulationStarted(object sender, ManipulationStartedEventArgs args) { this.NavigationService.GoBack();
args.Complete(); args.Handled = true; }
protected override void OnManipulationStarted(ManipulationStartedEventArgs args) { ContentPanel.Background = new SolidColorBrush( Color.FromArgb(255, (byte)rand.Next(255), (byte)rand.Next(255), (byte)rand.Next(255)));
base.OnManipulationStarted(args); } }
|
Once again, when you touch
anywhere on the page except the TextBlock, the background changes to a random color. When
you touch the TextBlock, the handler
calls another method of NavigationService:
this.NavigationService.GoBack();
This call causes the program to go back to the page that
navigated to SecondPage.xaml, in this case, MainPage.xaml. Take a look
at the Navigate call in MainPage.cs
again:
this.NavigationService.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative));
Navigation
in a Silverlight program is based around XAML files in much the same way that navigation in a traditional Web environment is based
around HTML files. The actual instance of the SecondPage
class is created behind the scenes. The PhoneApplicationFrame instance in the application handles many of the
actual mechanics of navigation, but the public interface of PhoneApplicationFrame
also involves Uri objects and XAML files rather than instances of PhoneApplicationPage derivatives.
Let’s run the program.
The program begins with the main page, and you can touch the screen to
change the color:
Now touch the TextBlock that says “Navigate to 2nd Page” and the second
page comes into view:
You can touch that screen to
change to a different color:
Now touch the TextBlock that says “Go Back to 1st Page”.
(Alternatively, you can press the phone’s hardware Back button.) You’ll
be whisked back to the main page with the color just as you left it:
Now touch the TextBlock
again to navigate to the second page:
The background is black. The
second page does not
display the color you set when you last visited the second page. This
is very obviously a brand new instance of the SecondPage
class.
The navigation system in Silverlight for
Windows Phone is based around the metaphor of the last-in-first-out data
structure called the stack. I’ll
sometimes refer to the page calling Navigate
as the source
page and the page being navigated to as the destination page. When the source
page calls Navigate,
the source page is put on the stack and a new instance of the
destination page is created and displayed. When a page calls GoBack—or when the
user presses the phone’s hardware Back button—that page is abandoned,
and the page at the top of the stack is popped off and displayed.
Within a Silverlight
application, the phone’s Back button performs the same function as a
call to GoBack
except if you’re at the initial page of the program, in which case the
hardware Back button terminates the application.
Try this: Replace the GoBack
call in SecondPage.xaml.cs with the following:
this.NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
This is not the same as the GoBack
call. You won’t go back to the original instance of MainPage. This call causes SecondPage to navigate to a new instance of MainPage,
and if you keep pressing the TextBlock on each on the pages, you’ll build up a whole
stack of alternating MainPage and SecondPage
instances, each of which can have its own unique color. You’ll need to
use the hardware Back button on the phone to back up through all these
pages and finally terminate the application.
Navigate and GoBack are the
two basic methods of NavigationService, and it’s unlikely you’ll need to use anything
beyond these for your applications. Keep in mind that you’re coding for
a phone, and it doesn’t make a lot of sense to have very complex navigation schemes
within your program without also some way of reminding the user how the
current page was arrived at and how to unwind the process.
Perhaps the most important
use of secondary pages in a
Silverlight
application for the phone is to serve as dialog boxes. When a
program needs some information from the user, it navigates to a new
page to collection that information. The user enters the information,
and then goes back to the main page.