Implémenter la navigation entre deux pagesImplement navigation between two pages

Découvrez comment utiliser une trame et les pages pour activer une navigation pair à pair de base dans votre application.Learn how to use a frame and pages to enable basic peer-to-peer navigation in your app.

API importantes : classe Windows.UI.Xaml.Controls.Frame, classe Windows.UI.Xaml.Controls.Page, espace de noms Windows.UI.Xaml.NavigationImportant APIs: Windows.UI.Xaml.Controls.Frame class, Windows.UI.Xaml.Controls.Page class, Windows.UI.Xaml.Navigation namespace

Navigation pair à pair

1. Créer une application vide1. Create a blank app

  1. Dans le menu Microsoft Visual Studio, choisissez Fichier > Nouveau projet.On the Microsoft Visual Studio menu, choose File > New Project.
  2. Dans le volet gauche de la boîte de dialogue Nouveau projet, choisissez le nœud Visual C# > Windows > Universel ou Visual C++ > Windows > Universel.In the left pane of the New Project dialog box, choose the Visual C# > Windows > Universal or the Visual C++ > Windows > Universal node.
  3. Dans le volet central, choisissez Application vide.In the center pane, choose Blank App.
  4. Dans le champ Nom, entrez NavApp1, puis choisissez le bouton OK.In the Name box, enter NavApp1, and then choose the OK button. La solution est créée et les fichiers projet apparaissent dans l’Explorateur de solutions.The solution is created, and the project files appear in Solution Explorer.
  5. Pour exécuter le programme, choisissez Déboguer > Démarrer le débogage dans le menu, ou appuyez sur F5.To run the program, choose Debug > Start Debugging from the menu, or press F5. Une page vide s’affiche.A blank page is displayed.
  6. Pour arrêter le débogage et revenir à Visual Studio, quittez l’application ou cliquez sur Arrêter le débogage dans le menu.To stop debugging and return to Visual Studio, exit the app, or click Stop Debugging from the menu.

2. Ajouter des pages de base2. Add basic pages

Ajoutez ensuite deux pages au projet.Next, add two pages to the project.

  1. Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le nœud de projet BlankApp pour ouvrir le menu contextuel.In Solution Explorer, right-click the BlankApp project node to open the shortcut menu.
  2. Choisissez Ajouter > Nouvel élément dans le menu contextuel.Choose Add > New Item from the shortcut menu.
  3. Dans la boîte de dialogue Ajouter un nouvel élément, choisissez Page vide dans le volet du milieu.In the Add New Item dialog box, choose Blank Page in the middle pane.
  4. Dans le champ Nom, entrez Page1 (ou Page2), puis appuyez sur le bouton Ajouter.In the Name box, enter Page1 (or Page2) and press the Add button.
  5. Répétez les étapes 1 à 4 pour ajouter la deuxième page.Repeat steps 1-4 to add the second page.

Ces fichiers doivent maintenant être répertoriés comme faisant partie de votre projet NavApp1.Now, these files should be listed as part of your NavApp1 project.

C#C# C++C++
  • Page1.xamlPage1.xaml
  • Page1.xaml.csPage1.xaml.cs
  • Page2.xamlPage2.xaml
  • Page2.xaml.csPage2.xaml.cs
  • Page1.xamlPage1.xaml
  • Page1.xaml.cppPage1.xaml.cpp
  • Page1.xaml.hPage1.xaml.h
  • Page2.xamlPage2.xaml
  • Page2.xaml.cppPage2.xaml.cpp
  • Page2.xaml.hPage2.xaml.h

Ajoutez le contenu suivant à l’interface utilisateur de Page1.xaml.In Page1.xaml, add the following content:

  • Ajoutez un élément TextBlock nommé pageTitle en tant qu’élément enfant de la racine Grid.A TextBlock element named pageTitle as a child element of the root Grid. Modifiez la valeur de la propriété Text en la définissant sur Page 1.Change the Text property to Page 1.
<TextBlock x:Name="pageTitle" Text="Page 1" />
<HyperlinkButton Content="Click to go to page 2"
                 Click="HyperlinkButton_Click"
                 HorizontalAlignment="Center"/>

Ajoutez le code suivant dans le fichier code-behind Page1.xaml pour gérer l’événement Click de l’élément HyperlinkButton que vous avez ajouté pour accéder à Page2.xaml.In the Page1.xaml code-behind file, add the following code to handle the Click event of the HyperlinkButton you added to navigate to Page2.xaml.

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    this.Frame.Navigate(typeof(Page2));
}
void Page1::HyperlinkButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args)
{
    Frame().Navigate(winrt::xaml_typename<NavApp1::Page2>());
}
void Page1::HyperlinkButton_Click(Platform::Object^ sender, RoutedEventArgs^ e)
{
    this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(Page2::typeid));
}

Ajoutez le contenu suivant à l’interface utilisateur de Page2.xaml :In Page2.xaml, add the following content:

  • Ajoutez un élément TextBlock nommé pageTitle en tant qu’élément enfant de la racine Grid.A TextBlock element named pageTitle as a child element of the root Grid. Modifiez la valeur de la propriété Text en la définissant sur Page 2.Change the value of the Text property to Page 2.
<TextBlock x:Name="pageTitle" Text="Page 2" />
<HyperlinkButton Content="Click to go to page 1" 
                 Click="HyperlinkButton_Click"
                 HorizontalAlignment="Center"/>

Ajoutez le code suivant au fichier code-behind Page2.xaml pour gérer l’événement Click de l’élément HyperlinkButton pour naviguer vers Page1.xaml.In the Page2.xaml code-behind file, add the following code to handle the Click event of the HyperlinkButton to navigate to Page1.xaml.

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    this.Frame.Navigate(typeof(Page1));
}
void Page2::HyperlinkButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args)
{
    Frame().Navigate(winrt::xaml_typename<NavApp1::Page1>());
}
void Page2::HyperlinkButton_Click(Platform::Object^ sender, RoutedEventArgs^ e)
{
    this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(Page1::typeid));
}

Notes

Pour les projets C++, vous devez ajouter une directive #include dans le fichier d’en-tête de chaque page faisant référence à une autre page.For C++ projects, you must add a #include directive in the header file of each page that references another page. Pour l’exemple de navigation entre les pages présenté ici, le fichier page1.xaml.h contient #include "Page2.xaml.h", et à son tour, page2.xaml.h contient #include "Page1.xaml.h".For the inter-page navigation example presented here, page1.xaml.h file contains #include "Page2.xaml.h", in turn, page2.xaml.h contains #include "Page1.xaml.h".

Maintenant que nous avons préparé les pages, nous devons faire en sorte que Page1.xaml s’affiche au démarrage de l’application.Now that we've prepared the pages, we need to make Page1.xaml display when the app starts.

Ouvrez le fichier code-behind app.xaml et modifiez le gestionnaire OnLaunched.Open the App.xaml code-behind file and change the OnLaunched handler.

Ici, nous spécifions Page1 dans l’appel à Frame.Navigate au lieu de MainPage.Here, we specify Page1 in the call to Frame.Navigate instead of MainPage.

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    Frame rootFrame = Window.Current.Content as Frame;
 
    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == null)
    {
        // Create a Frame to act as the navigation context and navigate to the first page
        rootFrame = new Frame();
        rootFrame.NavigationFailed += OnNavigationFailed;
 
        if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
        {
            //TODO: Load state from previously suspended application
        }
 
        // Place the frame in the current Window
        Window.Current.Content = rootFrame;
    }
 
    if (rootFrame.Content == null)
    {
        // When the navigation stack isn't restored navigate to the first page,
        // configuring the new page by passing required information as a navigation
        // parameter
        rootFrame.Navigate(typeof(Page1), e.Arguments);
    }
    // Ensure the current window is active
    Window.Current.Activate();
}
void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
    Frame rootFrame{ nullptr };
    auto content = Window::Current().Content();
    if (content)
    {
        rootFrame = content.try_as<Frame>();
    }

    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == nullptr)
    {
        // Create a Frame to act as the navigation context and associate it with
        // a SuspensionManager key
        rootFrame = Frame();

        rootFrame.NavigationFailed({ this, &App::OnNavigationFailed });

        if (e.PreviousExecutionState() == ApplicationExecutionState::Terminated)
        {
            // Restore the saved session state only when appropriate, scheduling the
            // final launch steps after the restore is complete
        }

        if (e.PrelaunchActivated() == false)
        {
            if (rootFrame.Content() == nullptr)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                rootFrame.Navigate(xaml_typename<NavApp1::Page1>(), box_value(e.Arguments()));
            }
            // Place the frame in the current Window
            Window::Current().Content(rootFrame);
            // Ensure the current window is active
            Window::Current().Activate();
        }
    }
    else
    {
        if (e.PrelaunchActivated() == false)
        {
            if (rootFrame.Content() == nullptr)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                rootFrame.Navigate(xaml_typename<NavApp1::Page1>(), box_value(e.Arguments()));
            }
            // Ensure the current window is active
            Window::Current().Activate();
        }
    }
}
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
{
    auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);

    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == nullptr)
    {
        // Create a Frame to act as the navigation context and associate it with
        // a SuspensionManager key
        rootFrame = ref new Frame();

        rootFrame->NavigationFailed += 
            ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(
                this, &App::OnNavigationFailed);

        if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
        {
            // TODO: Load state from previously suspended application
        }
        
        // Place the frame in the current Window
        Window::Current->Content = rootFrame;
    }

    if (rootFrame->Content == nullptr)
    {
        // When the navigation stack isn't restored navigate to the first page,
        // configuring the new page by passing required information as a navigation
        // parameter
        rootFrame->Navigate(Windows::UI::Xaml::Interop::TypeName(Page1::typeid), e->Arguments);
    }

    // Ensure the current window is active
    Window::Current->Activate();
}

Notes

Le code utilise ici la valeur de retour de Navigate pour lever une exception d’application en cas d’échec de la navigation vers la fenêtre initiale de l’application.The code here uses the return value of Navigate to throw an app exception if the navigation to the app's initial window frame fails. Quand Navigate retourne true, la navigation a lieu.When Navigate returns true, the navigation happens.

À présent, générez et exécutez l’application.Now, build and run the app. Cliquez sur le lien « Click to go to page 2 ».Click the link that says "Click to go to page 2". La deuxième page indiquant « Page 2 » en haut doit être chargée et affichée dans le cadre.The second page that says "Page 2" at the top should be loaded and displayed in the frame.

À propos des classes Trame et PageAbout the Frame and Page classes

Avant d’ajouter d’autres fonctionnalités à notre application, examinons la façon dont les pages que nous venons d’ajouter prennent en charge la navigation dans l’application.Before we add more functionality to our app, let's look at how the pages we added provide navigation within our app.

Tout d’abord, un Frame, appelé rootFrame, est créé pour l’application dans la méthode App.OnLaunched du fichier code-behind App.xaml.First, a Frame called rootFrame is created for the app in the App.OnLaunched method in the App.xaml code-behind file. La classe Frame prend en charge diverses méthodes de navigation telles que Navigate, GoBack et GoForward, et les propriétés telles que BackStack, ForwardStack et BackStackDepth.The Frame class supports various navigation methods such as Navigate, GoBack, and GoForward, and properties such as BackStack, ForwardStack, and BackStackDepth.   La méthode Navigate est utilisée pour afficher le contenu dans ce Frame.The Navigate method is used to display content in this Frame. Par défaut, cette méthode charge MainPage.xaml.By default, this method loads MainPage.xaml. Dans notre exemple, Page1 est transmis à la méthode Navigate, qui charge alors Page1 dans le Frame.In our example, Page1 is passed to the Navigate method, so the method loads Page1 in the Frame.

Page1 est une sous-classe de la classe Page.Page1 is a subclass of the Page class. La classe Page possède une propriété en lecture seule Frame qui obtient l’objet Frame contenant l’objet Page.The Page class has a read-only Frame property that gets the Frame containing the Page. Lorsque le gestionnaire d’événements Click de l’objet HyperlinkButton de Page1 appelle this.Frame.Navigate(typeof(Page2)), l’objet Frame affiche le contenu de Page2.xaml.When the Click event handler of the HyperlinkButton in Page1 calls this.Frame.Navigate(typeof(Page2)), the Frame displays the content of Page2.xaml.

Pour finir, chaque fois qu’une page est chargée dans la trame, cette page est ajoutée comme une PageStackEntry à la BackStack ou ForwardStack de la trame. L’historique et la navigation vers l’arrière sont ainsi possibles.Finally, whenever a page is loaded into the frame, that page is added as a PageStackEntry to the BackStack or ForwardStack of the Frame, allowing for history and backwards navigation.

3. Passer des informations entre les pages3. Pass information between pages

Notre application navigue entre deux pages, mais elle n’effectue pour le moment rien d’intéressant.Our app navigates between two pages, but it really doesn't do anything interesting yet. Souvent, lorsqu’une application possède plusieurs pages, celles-ci doivent partager des informations.Often, when an app has multiple pages, the pages need to share information. Passons des informations de la première page à la deuxième.Let's pass some information from the first page to the second page.

Dans Page1.xaml, remplacez l’objet HyperlinkButton que vous avez ajouté précédemment par l’objet StackPanel suivant.In Page1.xaml, replace the HyperlinkButton you added earlier with the following StackPanel.

Ici, nous ajoutons une étiquette TextBlock et un objet TextBox (name) pour entrer une chaîne de texte.Here, we add a TextBlock label and a TextBox name for entering a text string.

<StackPanel>
    <TextBlock HorizontalAlignment="Center" Text="Enter your name"/>
    <TextBox HorizontalAlignment="Center" Width="200" Name="name"/>
    <HyperlinkButton Content="Click to go to page 2" 
                     Click="HyperlinkButton_Click"
                     HorizontalAlignment="Center"/>
</StackPanel>

Dans le gestionnaire d’événements HyperlinkButton_Click du fichier code-behind Page1.xaml, ajoutez un paramètre faisant référence à la propriété Text de name TextBox à la méthode Navigate.In the HyperlinkButton_Click event handler of the Page1.xaml code-behind file, add a parameter referencing the Text property of the name TextBox to the Navigate method.

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    this.Frame.Navigate(typeof(Page2), name.Text);
}
void Page1::HyperlinkButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args)
{
    Frame().Navigate(winrt::xaml_typename<NavApp1::Page2>(), winrt::box_value(name().Text()));
}
void Page1::HyperlinkButton_Click(Platform::Object^ sender, RoutedEventArgs^ e)
{
    this->Frame->Navigate(Windows::UI::Xaml::Interop::TypeName(Page2::typeid), name->Text);
}

Dans Page2.xaml, remplacez l’objet HyperlinkButton que vous avez ajouté précédemment par l’objet StackPanel suivant.In Page2.xaml, replace the HyperlinkButton you added earlier with the following StackPanel.

Ici, nous ajoutons un TextBlock pour afficher la chaîne de texte transmise à partir de Page1.Here, we add a TextBlock for displaying the text string passed from Page1.

<StackPanel>
    <TextBlock HorizontalAlignment="Center" Name="greeting"/>
    <HyperlinkButton Content="Click to go to page 1" 
                     Click="HyperlinkButton_Click"
                     HorizontalAlignment="Center"/>
</StackPanel>

Dans le fichier code-behind Page2.xaml, remplacez la méthode OnNavigatedTo par les éléments suivants :In the Page2.xaml code-behind file, add the following to override the OnNavigatedTo method:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (e.Parameter is string && !string.IsNullOrWhiteSpace((string)e.Parameter))
    {
        greeting.Text = $"Hi, {e.Parameter.ToString()}";
    }
    else
    {
        greeting.Text = "Hi!";
    }
    base.OnNavigatedTo(e);
}
void Page2::OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs const& e)
{
    auto propertyValue{ e.Parameter().as<Windows::Foundation::IPropertyValue>() };
    if (propertyValue.Type() == Windows::Foundation::PropertyType::String)
    {
        greeting().Text(L"Hi, " + winrt::unbox_value<winrt::hstring>(e.Parameter()));
    }
    else
    {
        greeting().Text(L"Hi!");
    }
    __super::OnNavigatedTo(e);
}
void Page2::OnNavigatedTo(NavigationEventArgs^ e)
{
    if (dynamic_cast<Platform::String^>(e->Parameter) != nullptr)
    {
        greeting->Text = "Hi, " + e->Parameter->ToString();
    }
    else
    {
        greeting->Text = "Hi!";
    }
    ::Windows::UI::Xaml::Controls::Page::OnNavigatedTo(e);
}

Exécutez l’application, tapez votre nom dans la zone de texte, puis cliquez sur le lien indiquant Click to go to page 2.Run the app, type your name in the text box, and then click the link that says Click to go to page 2.

Lorsque l’événement Click de l’objet HyperlinkButton de Page1 appelle this.Frame.Navigate(typeof(Page2), name.Text), la propriété name.Text est transmise à Page2, et la valeur des données d’événement est utilisée pour le message affiché sur la page.When the Click event of the HyperlinkButton in Page1 calls this.Frame.Navigate(typeof(Page2), name.Text), the name.Text property is passed to Page2, and the value from the event data is used for the message displayed on the page.

4. Mettre en cache une page4. Cache a page

Le contenu et l’état de la page ne sont pas mis en cache par défaut. Pour le faire, vous devez les activer dans chaque page de votre application.Page content and state is not cached by default, so if you'd like to cache information, you must enable it in each page of your app.

Dans notre exemple pair à pair de base, il n’existe aucun bouton Précédent (nous expliquons la navigation vers l’arrière dans Navigation vers l’arrière, mais si vous avez cliqué sur un bouton Précédent dans Page2, l’objet TextBox (et tout autre champ) de Page1 serait défini à son état par défaut.In our basic peer-to-peer example, there is no back button (we demonstrate back navigation in backwards navigation), but if you did click a back button on Page2, the TextBox (and any other field) on Page1 would be set to its default state. Un moyen de contourner ce problème consiste à utiliser la propriété NavigationCacheMode pour spécifier l’ajout d’une page dans le cache de la page du cadre.One way to work around this is to use the NavigationCacheMode property to specify that a page be added to the frame's page cache.

Dans le constructeur de Page1, vous pouvez définir NavigationCacheMode sur Enabled pour conserver toutes les valeurs de contenu et d’état de la page jusqu’à ce que le cache de pages de la trame soit saturé.In the constructor of Page1, you can set NavigationCacheMode to Enabled to retains all content and state values for the page until the page cache for the frame is exceeded. Définissez NavigationCacheMode sur Required si vous voulez ignorer les limites CacheSize, qui spécifient le nombre de pages de l’historique de navigation qui peuvent être mises en cache pour la trame.Set NavigationCacheMode to Required if you want to ignore CacheSize limits, which specify the number of pages in the navigation history that can be cached for the frame. Toutefois, n’oubliez pas que la taille limite du cache peut être cruciale, selon les limites de mémoire d’un appareil.However, keep in mind that cache size limits might be crucial, depending on the memory limits of a device.

public Page1()
{
    this.InitializeComponent();
    this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
}
Page1::Page1()
{
    InitializeComponent();
    NavigationCacheMode(Windows::UI::Xaml::Navigation::NavigationCacheMode::Enabled);
}
Page1::Page1()
{
    this->InitializeComponent();
    this->NavigationCacheMode = Windows::UI::Xaml::Navigation::NavigationCacheMode::Enabled;
}