Home > Articles > Programming > Windows Programming

This chapter is from the book

This chapter is from the book

Page Navigation

Windows Phone navigation in Silverlight is based on the Silverlight for the browser navigation model. The navigation class model looks a little different in the phone SDK however. Rather than Silverlight 4’s Frame and Page controls, Silverlight for Windows Phone apps use the subclasses PhoneApplicationFrame and the PhoneApplicationPage (see Figure 3.4).

Figure 3.4

Figure 3.4. The PhoneApplicationFrame and PhoneApplicationPage classes are derived from the Frame and Page classes, respectively.

Page navigation in Silverlight for Windows Phone works in much the same way as page navigation in a web browser. PhoneApplicationFrame is analogous to the web browser, coordinating page transitions within your app.

Figure 3.5 depicts the display elements of a Silverlight for Windows Phone app.

Figure 3.5

Figure 3.5. Display elements of a Silverlight for Windows Phone app

The PhoneApplicationFrame is the host for PhoneApplicationPages and reserves space for the system tray and the application bar. The PhoneApplicationPage consumes all remaining space after the system tray and the application bar.

Navigation Using Unmapped URIs

There are numerous ways of allowing the user to perform page navigation. This section looks at using Buttons with code-beside to open external URLs, and at HyperlinkButtons, which can rely solely on XAML. In subsequent chapters you explore other techniques to perform navigation including the use of commands and a custom navigation service.

Internal URIs

When navigating to PhoneApplicationPages within an application, URIs either must be relative to the root directory of the project, and use the relative path syntax, as shown in the following excerpt:

Uri uri = new Uri("/DirectoryName/PageName.xaml", UriKind.Relative);

or they must use the relative component URI format, such as that used in the following example:

Uri uri = new Uri("/AssemblyName;component/PageName.xaml", UriKind.Relative);

The assembly name segment must be the name of an assembly that is locatable at runtime. The name of a project’s output assembly can be found in the project properties editor by right-clicking on the project node in the Solution Explorer and selecting Properties, or by pressing Alt+Enter.

The HyperlinkButton control can be used to allow the user to navigate directly to a page within your application, as shown:

<HyperlinkButton NavigateUri="/Directory/PageName.xaml" Content="Internal Page" />

External Navigation Using the Button Control

The Button control is a flexible way for determining user intent. A Button can be used for navigation by subscribing to its Click event, as shown in the following excerpt from the ProductDetailsView.xaml in the downloadable sample code:

<Button Click="Button_ExternalLink_Click"
       Tag="{Binding Product.ExternalUrl}"
       Content="External Page" />

The WebBrowserTask allows you to navigate to external URIs using the phone’s built-in web browser: Internet Explorer. This causes your app to be deactivated while the user views the page. You explore tasks in more detail in Chapter 12.

To provide the WebBrowserTask with the location of the web page, use the button’s Tag property. The Click event handler, which initiates the WebBrowserTask, is shown in the following excerpt:

void Button_ExternalLink_Click(object sender, RoutedEventArgs e)
   {
   FrameworkElement button = sender as FrameworkElement;
   if (button == null || button.Tag == null)
   {
       return;
   }
   WebBrowserTask task = new WebBrowserTask
   {
       URL = button.Tag.ToString()
   };
   task.Show();
}

External Navigation Using the HyperlinkButton Control

The disadvantage of using a Button control for links to external content is that it does not provide the familiar look and feel of a hyperlink. The HyperlinkButton control provides an easier way for navigating to pages within an application. There is a trick to using the HyperlinkButton with external URIs. Set its TargetName property to _blank, as shown in the following example:

<HyperlinkButton TargetName="_blank" NavigateUri="http://create.msdn.com"
               Content="http://create.msdn.com" />

Hosting Web Content Within an App

An alternative to using the phone’s built-in Internet Explorer app is to host the content in a Microsoft.Phone.Controls.WebBrowser control.

The following excerpt from the WebBrowserView.xaml page, in the downloadable sample code, shows a WebBrowser placed within the main content grid of a page:

<Grid x:Name="ContentGrid" Grid.Row="1">
    <phone:WebBrowser Source="{Binding Url}"/>
</Grid>

Here, the Source property of the WebBrowser is bound to the Url property of the viewmodel. The WebBrowser control is discussed in greater detail in Chapter 7, “Media and Web Elements.”

A dedicated web browser page can be used in your app to host all external content. To launch the dedicated web browser page, a relative URI can be constructed using the Binding.StringFormat property, as shown in the following excerpt:

<HyperlinkButton
    NavigateUri="{Binding ExternalUrl, StringFormat=/WebBrowser/\{0\}}"
    Content="External Page" />

Backslashes are used to escape the curly brackets in the StringFormat value.

The StringFormat property transforms the HyperlinkButton’s binding expression into the following:

string.Format("/WebBrowser/{0}", ExternalUrl);

URI mapping is used to pass the external URL as a query string parameter. This is explored further in a later section.

Passing Page Arguments Using Query Strings

Query strings allow for key value pairs to be embedded in a URL and passed to a page. Just like HTML web applications, Silverlight uses query string parameters for interpage communication.

The PhoneApplicationPage.NavigationContext property, which is initialized after the page is created, is used to retrieve the query string. Its QueryString property is an IDictionary of string key and value pairs. The following excerpt from the WebBrowserView.xaml, in the downloadable sample code, demonstrates how to retrieve a query string value:

void OnLoaded(object sender, RoutedEventArgs e)
{
    string url;
    if (NavigationContext.QueryString.TryGetValue("url", out url))
    {
        ViewModel.LoadPage(url);
    }
}

Navigation History Stack

The Silverlight navigation infrastructure maintains a history of pages that have been loaded. Each time an app navigates to a different page, the current page’s OnNavigatedFrom method is called and the page is placed on the history stack (see Figure 3.6).

Figure 3.6

Figure 3.6. Pages are placed on the history stack.

While on the history stack, the page remains in memory unless the application is tombstoned or closed. This means that subscribing to the PhoneApplicationService.Deactivated event provides the page with the opportunity to save its transient state. It is, however, preferable to use the page’s OnNavigatedFrom method for the saving of page state.

Using the Deactivate event to save page state runs the risk of slowing down deactivation when all pages on the history stack are saving their state simultaneously.

Restoration of transient state should occur with the page’s OnNavigatedTo method. The OnNavigatedTo method is called when the PhoneApplicationFrame navigates to the page. This is triggered by the following actions:

  • Navigation to a specified page URI occurs using one of various navigation methods such as the PhoneApplicationFrame.Navigate method.
  • The NavigationService.GoBack method is called.
  • The user presses the hardware Back button.
  • The page is the current page when the app moves from the tombstoned or dormant state to the running state.
  • The page is the app’s start page and the app is launched.

URI Mapping

Relying on URIs that include the full path to each page in your app can make your app brittle and makes it harder to change the physical location of individual pages. If a page is moved, all references to that file must be updated. This can lead to maintainability issues as the size of the project grows.

The URI mapping system of Silverlight allows requests for a URI to be routed to another URI, and uses a single configuration point for the management of page URIs. Mapped URIs can be made shorter and are, thus, less subject to typographical errors. They also allow the exclusion of technology specific information, such as the .xaml page file extension, making it easier to retarget business logic for different platforms.

To use URI mapping, you must assign a System.Windows.Navigation.UriMapper instance to the UriMapper property of an app’s PhoneApplicationFrame. This can be done in XAML, as shown in the following excerpt from the App.xaml file in the downloadable sample code:

<Application
   x:Class="DanielVaughan.WindowsPhone7Unleashed.Examples.App"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

       <Application.RootVisual>
           <phone:PhoneApplicationFrame x:Name="RootFrame">
               <phone:PhoneApplicationFrame.UriMapper>
                   <navigation:UriMapper>
                       <navigation:UriMapper.UriMappings>
                           <navigation:UriMapping
                             Uri="/ProductDetails/{productId}"
        MappedUri="/Navigation/ProductDetailsView.xaml?productId={productId}" />
                           <navigation:UriMapping Uri="/WebBrowser/{url}"
                       MappedUri="/WebBrowser/WebBrowserView.xaml?url={url}" />
                       </navigation:UriMapper.UriMappings>
                   </navigation:UriMapper>
               </phone:PhoneApplicationFrame.UriMapper>
           </phone:PhoneApplicationFrame>
       </Application.RootVisual>

       <!-- Content omitted. -->
</Application>

The UriMapping class contains a Uri property and a MappedUri property. When navigation is requested from the Uri value, it is rerouted to the MappedUri property.

By using the curly brace syntax, as shown in the previous excerpt, a substring of the requested URI can be transplanted into the rerouted MappedUri value. This is especially useful when you want to target the same page using different URIs and allows the query string to be used to convey the action to be undertaken by the page.

In the previous excerpt you see a UriMapping for the ProductDetailsView page. The ProductDetailsView displays detailed information for a particular product, identified by a query string parameter. When navigating to the ProductDetails page, if the requested URL is /ProductDetails/2, this is rerouted to /Navigation/ProductDetailsView.xaml?productId=2.

If you were to request the ProductDetailsView page using the NavigationService, as shown in the following example, the request would be rerouted accordingly:

NavigationService.Source = new Uri("/ProductDetails/2", UriKind.Relative);

The product to be displayed can then be determined in the ProductsDetailsView by reading the productId query string parameter, as demonstrated in the following excerpt:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
   base.OnNavigatedTo(e);
   string productIdString = NavigationContext.QueryString["productId"];
   int productId = int.Parse(productIdString);
ViewModel.LoadProduct(productId);
}

You see later in this chapter how the viewmodel uses the product ID to retrieve the product information from a WCF service.

Navigation Using the NavigationService

The PhoneApplicationPage class exposes a public NavigationService property, which allows direct control over navigation.

The NavigationService.Navigate method causes the frame to load the specified PhoneApplicationPage, like so:

NavigationService.Navigate(
   new Uri("/DirectoryName/PageName.xaml", UriKind.Relative));

The URI must be either a path relative to the project’s root directory, as shown in the previous example, or a relative component URI such as in the following example:

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

The NavigationService.Source property allows you to retrieve the URI of the current page. Setting the Source property performs the same action as using the Navigate method; the frame loads the page at the specified URI. See the following example:

NavigationService.Source = new Uri(
        "/DirectoryName/PageName.xaml", UriKind.Relative);

Routing is also enabled for the NavigationService, which means that mapped URIs can be used instead of relative URIs.

If you examine the API of the NavigationService, you will likely wonder what the difference is between the CurrentSource property and the Source property. The answer is that the CurrentSource property does not change until navigation has completed. Conversely, the Source property changes as soon as navigation is initiated.

Backward Navigation

The NavigationService maintains the app’s navigation history, via an internal Journal instance. This allows the GoBack method of the NavigationService to move to the previous page in the history stack.

Forward Navigation

Unlike Silverlight for the browser, the GoForward method of the NavigationService does not allow forward navigation and raises an InvalidOperationException when called. Consequently, the CanGoForward property always returns false.

Handling Page Navigation

The PhoneApplicationPage extends the System.Windows.Controls.Page class, which has a number of virtual methods called when the page is brought into view or removed from view by the PhoneApplicationFrame (see Figure 3.7).

Figure 3.7

Figure 3.7. PhoneApplicationPage inherits Page navigation methods.

The OnNavigatingFrom method is called before a page is removed from view by the PhoneApplicationFrame, and the OnNavigatedFrom method is called after navigation occurs. Conversely, the OnNavigatedTo method is called when the frame brings the page into view.

Cancelling Navigation

The OnNavigatingFrom method offers the opportunity to cancel navigation using the NavigatingCancelEventArgs parameter.

NavigatingCancelEventArgs has the following properties:

  • NavigationModeAn enum value that indicates the type of navigation. This value may be Back, Forward, New, or Refresh.
  • UriThe destination URI.
  • CancelSetting this value to true cancels the navigation.

The NavigationCancelEventArgs class subclasses CancelEventArgs, which provides the Cancel property. By setting this property to true, the page can prevent the navigation from occurring, as shown in the following excerpt:

protected override void OnNavigatingFrom(
    System.Windows.Navigation.NavigatingCancelEventArgs e)
{
    base.OnNavigatingFrom(e);
    MessageBoxResult boxResult = MessageBox.Show(
        "Leave this page?", "Question", MessageBoxButton.OKCancel);
    if (boxResult != MessageBoxResult.OK)
    {
        e.Cancel = true;
    }
}

Cross-Page Communication

Once navigation has occurred, there remains an opportunity for the previous page to interact with the current page from the previous page’s OnNavigatedFrom method. This is achieved using the Content property of the NavigationEventArgs, which provides the destination PhoneApplicationPage object.

To see this in action, place a breakpoint in the OnNavigatedFrom method. When the breakpoint is hit, notice that the page being navigated to has already been instantiated and is provided in the Content property of the NavigationEventArgs (see Figure 3.8).

Figure 3.8

Figure 3.8. The Content property of the NavigationEventArgs contains the page being navigated to.

The Uri property of the NavigationEventArgs contains the URI of the destination page, including any query string that may be present.

Page Redirection

The OnNavigatingFrom method allows you to intercept a navigation event and to even cancel the navigation if needed. Additionally, there may be times when you want to redirect the user to a different URI based on some conditional logic.

The NavigationService, however, does not support overlapping navigation. That is, you are unable to cancel an existing navigation and immediately commence another.

You can, however, cancel navigation and schedule navigation to a different Uri using the page’s Dispatcher property, as shown in the following excerpt:

protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
    if (e.Uri.ToString().Contains("RequestedUrl"))
    {
        e.Cancel = true;
        /* Perform the redirect on the UI thread. */
        Dispatcher.BeginInvoke(() => NavigationService.Navigate(
            new Uri("RedirectUrl", UriKind.Relative)));
    }

    base.OnNavigatingFrom(e);
}

By using the Dispatcher to invoke the lambda expression, which performs the call to the NavigationService, you allow the current navigation to complete first. This works because the UI thread can be thought of as a queue of prioritized delegates, all waiting in turn to be executed. Once all the Navigating event handlers have been serviced, the delegate represented by the lambda expression will be taken out of the queue and performed by the UI thread. This technique, of using the Dispatcher to enqueue an action, is also useful when working with some UI controls, whose event handlers may be called before the control is finished reacting to a user action.

Hardware Back Button

The hardware Back button is analogous to the Back button on a web browser. However, when the user presses the Back button, past the first page of a phone app, the app is closed. This is in contrast to the phone’s hardware start button, which merely causes an app to be deactivated.

To determine whether navigation is occurring because the hardware Back button was pressed or the navigation was initiated by a call to NavigationService.GoBack, use the NavigatingEventArgs.NavigationMode property as shown:

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);
    if (e.NavigationMode == NavigationMode.Back)
    {
        // Back button pressed.
    }
}

The Back key button can also be cancelled by overriding the PhoneApplicationPage.OnBackKeyPress, as shown in the following excerpt:

protected override void OnBackKeyPress(CancelEventArgs e)
{
    base.OnBackKeyPress(e);
 
    e.Cancel = true;
}

OnBackKeyPress is called before OnNavigatedFrom, and if the Back button is cancelled, then OnNavigatedFrom is not called at all.

Creating an Application Splash Screen

Windows Phone Silverlight projects have baked-in support for application splash screens. To create a splash screen it is simply a matter of placing a jpg image called SplashScreenImage.jpg, with the dimensions of 480 by 800 pixels, in the root directory of your project. Ensure that its Build Action is set to Content (see Figure 3.9).

Figure 3.9

Figure 3.9. Creating an application splash screen

Using an image for a splash screen does not, however, prevent an application from being closed by the OS if the first page takes longer than 10 seconds to load. If your application’s first page takes longer than this to load, it is best to overlay the content with a loading indicator and perform the time consuming initialization on a background thread. Once loading is complete, the indicator can be dismissed.

The ProductsView and ProductsViewModel classes, located in the Navigation directory of the WindowsPhone7Unleashed.Examples project in the downloadable sample code, demonstrate this principle (see Figure 3.10).

Figure 3.10

Figure 3.10. A custom loading screen

The ProductsView page uses a StackPanel to present an indeterminate progress bar to the user while the viewmodel is loading, as shown in the following excerpt:

<StackPanel Grid.Row="1"
           Visibility="{Binding Loaded,
           Converter={StaticResource BooleanToVisibilityConverter},
           ConverterParameter=Collapsed}"
           Height="150" >
    <TextBlock Text="Loading..." Style="{StaticResource PhoneTextTitle2Style}"
           HorizontalAlignment="Center" Margin="20"/>
    <toolkit:PerformanceProgressBar IsIndeterminate="True" />
</StackPanel>

The Visibility property of the StackPanel is assigned via a binding to the viewmodel’s Loaded property. To convert the boolean Loaded property to a Visibility type, a custom IValueConverter called BooleanToVisibilityConverter is used (see Listing 3.3). The class is located in the ValueConverters directory of the WindowsPhone7Unleashed project, in the downloadable sample code.

Listing 3.3. BooleanToVisibility Class

public class BooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        string paramValue = (string)parameter;

        if (value == null || (bool)value)
        {
            return paramValue == "Collapsed"
                ? Visibility.Collapsed : Visibility.Visible;
        }

        return paramValue == "Collapsed"
            ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        string paramValue = (string)parameter;
        if (value == null || (Visibility)value == Visibility.Visible)
        {
            return paramValue != "Collapsed";
        }

        return paramValue == "Collapsed";
    }
}

The ConverterParameter attribute determines what value to assign to the Visibility property if the binding value is true. If the Loaded property of the viewmodel is true, then the Visibility property will set to Visibility.Visible.

To hide the rest of the content during loading, the same technique is employed for the main content control.

<StackPanel Grid.Row="1" Margin="10"
              Visibility="{Binding Loaded,
                 Converter={StaticResource BooleanToVisibilityConverter},
                 ConverterParameter=Visible}">
    <ScrollViewer>
       <!-- Content omitted. -->
       <ScrollViewer>
</StackPanel>

Here the ConverterParameter attribute is set to Visible, so that its Visibility is set to Visible when the viewmodel’s Loaded property is true and Collapsed when it is false.

The code listings for the ProductsView page and associated files are provided in the following section.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020