NavFx Part 5 - The Many Faces of GoToPage

Following a request for some changes to NavFx to support single step navigation I have added several new overloads of the Navigator.GoToPage method.  With so many overloads I thought it would a good idea to document them all in a seperate article.

In this article I am going to briefly recap the original navigation steps then I am going to document each of the GoToPage overloads.

Original NavFx Process

Other articles cover the use of NavFx in detail, but I want to recap the coding steps you would perform during startup and to navigate from page to page in your NavFx application.

Initialisation

Typically during startup of your application you will prepare a single instance of NavFx.Navigator to use througout the application.  You will most likely instantiate your primary or only tranition handler at this point and set the Tranistor property of the Application with a reference to this..  This will normally be done in the constructor or Startup event of your Application class.  If you are using the NavFx.Application base class provided this is all done for you using the NavFx.SimpleTransitor.  You can of course use the base class and set the Transitor property to another implementation, you can also change the ITransitor at any time in your application according to your needs.

Navigation

To navigate to another page you simply call one of the GoToPage methods.  Whichever overload you use Navigator will pass references to the current and target pages to the TransitionPage method that an ITransitor must implement.  It is the responsiblity of the TransitionPage method to display the target page as required by the application.  The SimpleTransitor provide with NavFx adds a step to this process.  With SimpleTransitor to navigate to a new page you must first make sure the Target property is set, then call a GoToPage method.  When Navigator delegates to the TransitionPage method of SimpleTransitor it is the Target property that determines where the target page is displayed.

Changes

In the first release of NavFx the Target property was specific to the SimpleTransitor, but I have now changed ITransitor to require a Target property and provided an abstract TransitorBase that has a default implementation for Target.  With this change I have been able to add several new overloads of GoToPage that support single step navigation when using the Target property as the SimpleTransitor does.  You are still free to implement a custom ITransitor that does not use the Target property and lets the TransitionPage method determine how to display the target page, you can simply do nothing in your implementation of the property or throw a NotSupportedException.

The Many Faces of GoToPage

In this section I am going to document each of the overloads for GoToPage, but first I want to provide a basic outline of page that acts as a host for the page  being navigated to in all the example statements.  If you have read my previous articles you will be familiar with the Shell page I use.

Shell.xaml is a navfx:HostPage and provides the basic navigation and layout of the application.  It defines a container where hosted pages are displayed like this.  On startup a Shell is set as the RootVisual of Application, which means SimpleTransitor will identify Shell as the real target when the Target propety is set to Application.Current.

<Grid x:Name="contentPanel" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Grid>

In code behind the following SetContent method is defined

public override void SetContent(UserControl newContent)
{
    this.contentPanel.Children.Clear();
    this.contentPanel.Children.Add(newContent);
}

The TransitionPage method of SimpleTransitor does one of two things.  If  it detects the Target implements IHostPage it calls the SetContent method otherwise it replaces the children of the target (for example if it detects Target derives from Panel)

All of the GoToPage methods result in a call to the TransitionPage method of the current Transitor of the Navigator.

Home.xaml is a content page designed to be displayed in the content panel of Shell.

External1.xaml is content page in an external Silverlight Library designed to be displayed in the content panel of Shell

All of the examples in the following achieve the same goals.

  1. Ensure the Target property of the SimpleTransitor is set
  2. Ensure the target page is registered
  3. Display the target page
GoToPage(string path)

This is the most basic form of GoToPage and is designed to navigate to a page that has been registered with Navigator.  Use this only if you know the page has been registered and a reference to it is in the page cache and you do not intend to use the NextPage or PreviousPage methods of Navigator.  Navigator maintains a CurrentIndex that tracks the index of the last page navigated to, for performance reasons this overload does not update the CurrentIndex.

Application.Current.GetTransitor<SimpleTransitor>().Target = Application.Current;
Home homePage = new Home();
Application.Current.GetNavigator().RegisterPage(homePage);
Application.Current.GetNavigatory().GoToPage("Home");

GoToPage(string path, bool updateIndex)

This overload is designed to navigate to a page that has been registered with Navigator.  Use this if you know the page has been registered and a reference to it is in the page cache and you want to use the NextPage and PreviousPage methods of Navigator.  The updateIndex argument allows you to explicitly indicate whether CurrentIndex should be updated.

Application.Current.GetTransitor<SimpleTransitor>().Target = Application.Current;
Home homePage = new Home();
Application.Current.GetNavigator().RegisterPage(homePage);
Application.Current.GetNavigator().GoToPage("Home", true);

GoToPage(string path, bool updateIndex, Uri libraryUri)

This overload is designed to navigate to a page from an external library that may or may not have been loaded and registered with Navigator.  If the path is not matched in the page cache the library is loaded and all contained pages are registered with Navigator.  The updateIndex argument allows you to explicitly indicate whether the CurrentIndex should be updated.  libraryUri must be a relative Uri to a dll that is in the same location as the .xap file.

Application.Current.GetTransitor<SimpleTransitor>().Target = Application.Current;
Uri libraryUri = new Uri(@"MyPages.dll", UriKind.Relative);
Application.Current.GetNavigator().GoToPage("External1", true, libraryUri);

GoToPage(string path, bool updateIndex, string libraryUrl)

This overload is designed to navigate to a page from an external library that may or may not have been loaded and registered with Navigator.  It is designed to eliminate the need for developers to create a Uri instance, this is created for you based on the libraryUrl specified.  If the path is not matched in the page cache a Uri is created from the url and the library is loaded and all contained pages are registered with Navigator.  The updateIndex argument allows you to explicitly indicate whether the CurrentIndex should be updated.  libraryUrl must be relative Url to a dll that is in the same location as the .xap file.

Application.Current.GetTranisitor<SimpleTransitor>().Target = Application.Current;
Application.Current.GetNavigator().GoToPage("External1", true, @"MyPages.dll");

GoToPage(string path, string targetPath)

This overload is designed to navigate to a page that is already registered with Navigator using another page that is already registered with Navigator as a host.  The method obtains a reference to targetPath from the page cache and sets the Target using the reference, it then navigates to the page with path.  For performance reasons this method does not update CurrentIndex, so only use this overload if you do not use the NextPage and PreviousPage methods of Navigator.

Shell shellPage = new Shell();
Application.Current.GetNavigator().RegisterPage(shellPage);
Home homePage = new Home();
Application.Current.GetNavigator().RegisterPage(homePage);
Application.Current.GetNavigator().GoToPage("Home", "Shell");

GoToPage(string path, string targetPath, bool updateIndex)

This overload is designed to navigate to a page that has already been registered with Navigator using aother page that is already registered with Navigator as a host.  The method obtains a reference to targetPath from the page cache and sets the Target using the reference, it then navigates to the page with path.  The updateIndex argument allows you to explicitly indicate whether CurrentIndex should be updated.

Shell shellPage = new Shell();
Application.Current.GetNavigator().RegisterPage(shellPage);
Home homePage = new Home();
Application.Current.GetNavigator().RegisterPage(homePage);
Application.Current.GetNavigator().GoToPage("Home", "Shell", true);

GoToPage(string path, string targetPath, bool updateIndex, Uri libraryUri)

This overload is designed to navigate to a page from an external library that may or may not have been loaded and registered with Navigator using another page that is already registered with Navigator as a host.  If the path is not matched in the page cache the library is loaded and all contained pages are registered with Navigator.  If targetPath is not already registered with Navigator an exception is thrown. The updateIndex argument allows you to explicitly indicate whether the CurrentIndex should be updated.  libraryUri must be a relative Uri to a dll that is in the same location as the .xap file.

Shell shellPage = new Shell();
Application.Current.GetNavigator().RegisterPage(shellPage);
Uri libraryUri = new Uri(@"MyPages.dll", UriKind.Relative);
Application.Current.GetNavigator().GoToPage("External1", "Shell", true, libraryUri);

GoToPage(string path, string targetPath, bool updatedIndex, string libraryUrl)

This overload is designed to navigate to a page from an external library that may or may not have been loaded and registered with Navigator using another page that is already registered with Navigator as a host.  It is designed to eliminate the need for developers to create a Uri instance, this is created for you based on the libraryUrl specified.  If the path is not matched in the page cache a Uri is created from the url and the library is loaded and all contained pages are registered with Navigator.  if targetPath is not already registered with Navigator an exception is thrown.  The updateIndex argument allows you to explicitly indicate whether the CurrentIndex should be updated.  libraryUrl must be relative Url to a dll that is in the same location as the .xap file.

Shell shellPage = new Shell();
Application.Current.GetNavigator().RegisterPage(shellPage);

Application.Current.GetNavigator().GoToPage("External1", "Shell", true, @"MyPages.dll");

GoToPage(string path, IHostPage targetPage, bool updateIndex)

This overload is designed to navigate to a page that has already been registered with Navigator using the IHostPage instance provided as a host.  The updateIndex argument allows you to explicitly indicate whether CurrentIndex should be updated.

Shell shellPage = new Shell();
Application.Current.GetNavigator().RegisterPage(shellPage);

Application.Current.GetNavigator().GoToPage("External1", shellPage, true);

GoToPage(string path, IHostPage targetPage, bool updateIndex, Uri libraryUri)

This overload is designed to navigate to a page from an external library that may or may not have been loaded and registered with Navigator using the IHostPage instance provided as a host.  The updateIndex argument allows you to explicitly indicate whether the CurrentIndex should be updated.  libraryUri must be a relative Uri to a dll that is in the same location as the .xap file.

Shell shellPage = new Shell();
Application.Current.GetNavigator().RegisterPage(shellPage);
Uri libraryUri = new Uri(@"MyPages.dll", UriKind.Relative);
Application.Current.GetNavigator().GoToPage("External1", shellPage, true, libraryUri);

GoToPage(string path, IHostPage targetPage, bool updateIndex, string libraryUrl)

This overload is designed to navigate to a page from an external library that may or may not have been loaded and registered with Navigator using the IHostPage instance provided as a host.  It is designed to eliminate the need for developers to create a Uri instance, this is created for you based on the libraryUrl specified.  The updateIndex argument allows you to explicitly indicate whether the CurrentIndex should be updated.  libraryUrl must be relative Url to a dll that is in the same location as the .xap file.

Shell shellPage = new Shell();
Application.Current.GetNavigator().RegisterPage(shellPage);

Application.Current.GetNavigator().GoToPage("External1", shellPage, true, @"MyPages.dll");

There you have it eleven different overloads of GoToPage to hopefully make it as easy to navigate from page to page with minimal code.  If you have the source code you will find three additional overloads but that take a System.Windows.Application as the target.  However the usefulness of these is dependent on the Transitor in use, not all ITransitor implementations will be able to support Application as a target, an example of this follows in my next article on implementing a custom Transitor.

Previous Article

Print | posted @ Sunday, July 27, 2008 9:20 AM

Comments on this entry:

Gravatar # re: NavFx Part 5 - The Many Faces of GoToPage
by Shemesh at 10/23/2008 1:25 PM

Mike hi,
any idea when will you release the binaries(dll) of the latest version that works with SL2 ?
  
Gravatar # re: NavFx Part 5 - The Many Faces of GoToPage
by MikeHanson at 10/23/2008 7:37 PM

I have been really busy lately and unable to do much with Silverlight or NavFx, but I will try to get something done this weekend to update the project and releases.
  
Gravatar # re: NavFx Part 5 - The Many Faces of GoToPage
by Jan Kinable at 10/24/2008 1:21 PM

While I was looking for a clean solution for navigating in SilverLight, I bounced on your project. I'm only working for a week now on SilverLight and found your solution a boost for my project.

I noticed your last change was one to provide a long list of overloads on the GoTo method. Intuitively, I ask the question wether it would be a better solution to provide some declarative input (from a xml file) to register all the pages. This would reduce the number of GoTo method's to one, just simple the keyname of the page. In the xml you could use somthing like this :

where Pinned and Library are optional.

The Navigator could register all the pages on start-up and instantiate them on demand.

I've been on several project where navigation via xml is common.


  
Gravatar # re: NavFx Part 5 - The Many Faces of GoToPage
by MikeHanson at 10/24/2008 5:40 PM

I think the idea of being able to register pages in bulk is a good one, but I don't think it should be the only way. I will look at adding something like this as part of the upgrade to RTM this weekend.
  
Gravatar # re: NavFx Part 5 - The Many Faces of GoToPage
by vagaa at 11/29/2008 12:43 PM

so good
so cool
  
Gravatar # re: NavFx Part 5 - The Many Faces of GoToPage
by Bydia at 7/13/2009 2:01 PM

Would be nice to see an online sample. If there is one, the link to it is not in a clear spot.
  
Gravatar # re: NavFx Part 5 - The Many Faces of GoToPage
by MikeHanson at 7/13/2009 2:36 PM

Bydia

There is no online sample, but there is a sample site in the source code that you can download from Source tab at www.codeplex.com/NavFx. It is not complete because I never seem to find the time these days but there should be enough to get you started.
  

Your comment:

Title:
Name:
Email:
Website:
 
Italic Underline Blockquote Hyperlink
 
 
Please add 4 and 2 and type the answer here: