Implémenter la navigation entre deux pages

Découvrez comment utiliser une trame et les pages pour activer une navigation pair à pair de base dans votre application.

Navigation pair à pair

Presque toutes les applications nécessitent une navigation entre les pages. Même une application simple avec une seule page de contenu a généralement une page de paramètres qui nécessite une navigation. Dans cet article, nous allons découvrir les principes de base de l’ajout d’un code XAML Page à votre application et de l’utilisation d’un Frame pour naviguer entre les pages.

Important

Nous utilisons le modèle Application vide de Microsoft Visual Studio pour cet exemple. Il existe des différences dans les modèles pour les applications SDK d'application Windows/WinUI 3 et les applications UWP. Veillez donc à sélectionner l’onglet approprié pour votre type d’application.

1. Créer une application vide

Pour créer une application vide dans Visual Studio :

  1. Pour configurer votre ordinateur de développement, consultez Installer des outils pour le SDK d’application Windows.
  2. Dans la fenêtre de démarrage de Microsoft Visual Studio, sélectionnez Créer un projet, OU, dans le menu Visual Studio, choisissez Fichier>Nouveau>projet.
  3. Dans les filtres déroulants de la boîte de dialogue Créer un projet , sélectionnez C# ou C++, Windows et WinUI, respectivement.
  4. Sélectionnez le modèle de projet Blank App, Packaged (WinUI 3 in Desktop), puis cliquez sur Suivant. Ce modèle crée une application de bureau avec une interface utilisateur WinUI 3.
  5. Dans la zone Nom du projet , entrez BasicNavigation, puis cliquez sur Créer.
  6. Pour exécuter le programme, choisissez Déboguer>Démarrer le débogage dans le menu, ou appuyez sur F5. Générez et exécutez votre solution sur l’ordinateur de développement pour vérifier que l’application s’exécute sans erreur. Une page vide s’affiche.
  7. Pour arrêter le débogage et revenir à Visual Studio, quittez l’application ou cliquez sur Arrêter le débogage dans le menu.
  8. Supprimez tout exemple de code inclus dans le modèle des MainWindow.xaml fichiers et MainWindow code-behind.

Conseil

Pour plus d’informations, consultez Créer votre premier projet WinUI 3 (SDK d'application Windows).

2. Utiliser un cadre pour naviguer entre les pages

Lorsque votre application a plusieurs pages, vous utilisez un frame pour naviguer entre elles. La Frame classe prend en charge différentes méthodes de navigation telles que Navigate, GoBack et GoForward, ainsi que des propriétés telles que BackStack, ForwardStack et BackStackDepth.

Lorsque vous créez un projet SDK d'application Windows dans Visual Studio, le modèle de projet crée une MainWindow classe (de type Microsoft.UI.Xaml.Window). Toutefois, il ne crée pas de frame ou de page et ne fournit aucun code de navigation.

Pour activer la navigation entre les pages, ajoutez un Frame en tant qu’élément racine de MainWindow. Vous pouvez le faire dans le remplacement de la méthode Application.OnLaunched dans le App.xaml fichier code-behind. Ouvrez le App fichier code-behind, mettez à jour le OnLaunched remplacement et gérez l’événement NavigationFailed , comme illustré ici.

// App.xaml.cs

protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
    m_window = new MainWindow();

    // Create a Frame to act as the navigation context and navigate to the first page
    Frame rootFrame = new Frame();
    rootFrame.NavigationFailed += OnNavigationFailed;
    // Navigate to the first page, configuring the new page
    // by passing required information as a navigation parameter
    rootFrame.Navigate(typeof(MainPage), args.Arguments);

    // Place the frame in the current Window
    m_window.Content = rootFrame;
    // Ensure the MainWindow is active
    m_window.Activate();
}

void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
    throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
// App.xaml.h

// Add after OnLaunched declaration.
void OnNavigationFailed(IInspectable const&, Microsoft::UI::Xaml::Navigation::NavigationFailedEventArgs const&);

///////////////
// App.xaml.cpp

void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
    window = make<MainWindow>();
    Frame rootFrame = Frame();
    rootFrame.NavigationFailed({ this, &App::OnNavigationFailed });
    rootFrame.Navigate(xaml_typename<BasicNavigation::MainPage>(), box_value(e.Arguments()));
    window.Content(rootFrame);
    window.Activate();
}

void App::OnNavigationFailed(IInspectable const&, NavigationFailedEventArgs const& e)
{
    throw hresult_error(E_FAIL, hstring(L"Failed to load Page ") + e.SourcePageType().Name);
}

Notes

Pour les applications avec une navigation plus complexe, vous utiliserez généralement un NavigationView comme racine de MainWindow et placez un Frame comme contenu de l’affichage de navigation. Pour plus d’informations, consultez Affichage de navigation.

La méthode Navigate est utilisée pour afficher le contenu dans ce Frame. Ici, MainPage.xaml est passé à la Navigate méthode, donc la méthode se charge MainPage dans le Frame.

Si la navigation vers la fenêtre initiale de l’application échoue, un NavigationFailed événement se produit et ce code lève une exception dans le gestionnaire d’événements.

3. Ajouter des pages de base

Le modèle Application vide ne crée pas plusieurs pages d’application pour vous. Avant de pouvoir naviguer entre les pages, vous devez ajouter des pages à votre application.

Pour ajouter un nouvel élément à votre application :

  1. Dans Explorateur de solutions, cliquez avec le bouton droit sur le nœud de BasicNavigation projet pour ouvrir le menu contextuel.
  2. Choisissez Ajouter un>nouvel élément dans le menu contextuel.
  3. Dans la boîte de dialogue Ajouter un nouvel élément , sélectionnez le nœud WinUI dans le volet gauche, puis choisissez Page vide (WinUI 3) dans le volet central.
  4. Dans la zone Nom , entrez et appuyez MainPage sur le bouton Ajouter .
  5. Répétez les étapes 1 à 4 pour ajouter la deuxième page, mais dans la zone Nom , entrez Page2.

À présent, ces fichiers doivent être répertoriés dans le cadre de votre BasicNavigation projet.

C# C++
  • MainPage.xaml
  • MainPage.xaml.cs
  • Page2.xaml
  • Page2.xaml.cs
  • MainPage.xaml
  • MainPage.xaml.cpp
  • MainPage.xaml.h
  • Page2.xaml
  • Page2.xaml.cpp
  • Page2.xaml.h

Important

Pour les projets C++, vous devez ajouter une #include directive dans le fichier d’en-tête de chaque page qui fait référence à une autre page. Pour l’exemple de navigation interpage présenté ici, le fichier mainpage.xaml.h contient #include "Page2.xaml.h", à son tour, page2.xaml.h contient #include "MainPage.xaml.h".

Les modèles de page C++ incluent également un exemple Button de code de gestionnaire et cliquez dessus que vous devez supprimer des fichiers XAML et code-behind de la page.

Ajouter du contenu aux pages

Dans MainPage.xaml, remplacez le contenu de la page existante par le contenu suivant :

<Grid>
    <TextBlock x:Name="pageTitle" Text="Main Page"
               Margin="16" Style="{StaticResource TitleTextBlockStyle}"/>
    <HyperlinkButton Content="Click to go to page 2"
                     Click="HyperlinkButton_Click"
                     HorizontalAlignment="Center"/>
</Grid>

Ce CODE XAML ajoute :

  • Élément TextBlock nommé pageTitle avec sa propriété Text définie sur Main Page en tant qu’élément enfant de la grille racine.
  • Élément HyperlinkButton utilisé pour accéder à la page suivante en tant qu’élément enfant de la grille racine.

Dans le MainPage fichier code-behind, ajoutez le code suivant pour gérer l’événement ClickhyperlinkButton que vous avez ajouté pour activer la navigation vers Page2.xaml.

// MainPage.xaml.cs

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    Frame.Navigate(typeof(Page2));
}
// pch.h
// Add this include in pch.h to support winrt::xaml_typename

#include <winrt/Windows.UI.Xaml.Interop.h>

////////////////////
// MainPage.xaml.h

void HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);

////////////////////
// MainPage.xaml.cpp

void winrt::BasicNavigation::implementation::MainPage::HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
    Frame().Navigate(winrt::xaml_typename<BasicNavigation::Page2>());
}

MainPage est une sous-classe de la classe Page. La Page classe a une propriété Frame en lecture seule qui obtient le Frame contenant .Page Lorsque le Click gestionnaire d’événements de dans MainPageHyperlinkButton appelle Frame.Navigate(typeof(Page2)), le Frame affiche le contenu de Page2.xaml.

Chaque fois qu’une page est chargée dans le cadre, cette page est ajoutée en tant que PageStackEntry à backstack ou forwardstack du frame, ce qui permet l’historique et la navigation vers l’arrière.

Maintenant, faites de même dans Page2.xaml. Remplacez le contenu de la page existante par le contenu suivant :

<Grid>
    <TextBlock x:Name="pageTitle" Text="Page 2"
               Margin="16" Style="{StaticResource TitleTextBlockStyle}"/>
    <HyperlinkButton Content="Click to go to main page"
                     Click="HyperlinkButton_Click"
                     HorizontalAlignment="Center"/>
</Grid>

Dans le Page2 fichier code-behind, ajoutez le code suivant pour gérer l’événement ClickhyperlinkButton pour accéder à MainPage.xaml.

// Page2.xaml.cs

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    Frame.Navigate(typeof(MainPage));
}
// Page2.xaml.h

void HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);

/////////////////
// Page2.xaml.cpp

void winrt::BasicNavigation::implementation::Page2::HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
    Frame().Navigate(winrt::xaml_typename<BasicNavigation::MainPage>());
}

Générez et exécutez l'application. Cliquez sur le lien « 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. Cliquez maintenant sur le lien de la page 2 pour revenir à la page principale.

4. Transmettre des informations entre les pages

Votre application navigue désormais entre deux pages, mais elle ne fait pas encore quelque chose d’intéressant. Souvent, lorsqu’une application possède plusieurs pages, celles-ci doivent partager des informations. Vous allez maintenant passer certaines informations de la première page à la deuxième page.

Dans MainPage.xaml, remplacez le HyperlinkButton que vous avez ajouté précédemment par le StackPanel suivant. Cela ajoute une étiquette TextBlock et une zone dename texte pour entrer une chaîne de texte.

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

Vous allez maintenant utiliser la deuxième surcharge de la Navigate méthode et passer le texte de la zone de texte comme deuxième paramètre. Voici la signature de cette Navigate surcharge :

public bool Navigate(System.Type sourcePageType, object parameter);
bool Navigate(TypeName const& sourcePageType, IInspectable const& parameter);

Dans le HyperlinkButton_Click gestionnaire d’événements du MainPage fichier code-behind, ajoutez un deuxième paramètre à la Navigate méthode qui fait référence à la Text propriété de la name zone de texte.

// MainPage.xaml.cs

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    Frame.Navigate(typeof(Page2), name.Text);
}
// MainPage.xaml.cpp

void winrt::BasicNavigation::implementation::MainPage::HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{ 
    Frame().Navigate(xaml_typename<BasicNavigation::Page2>(), winrt::box_value(name().Text()));
}

Dans Page2.xaml, remplacez le HyperlinkButton que vous avez ajouté précédemment par le suivant StackPanel. Cela ajoute un TextBlock pour afficher la chaîne de texte transmise à partir de MainPage.

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

Dans le Page2 fichier code-behind, ajoutez le code suivant pour remplacer la OnNavigatedTo méthode :

// Page2.xaml.cs

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (e.Parameter is string && !string.IsNullOrWhiteSpace((string)e.Parameter))
    {
        greeting.Text = $"Hello, {e.Parameter.ToString()}";
    }
    else
    {
        greeting.Text = "Hello!";
    }
    base.OnNavigatedTo(e);
}
// Page2.xaml.h

void Page2::OnNavigatedTo(Microsoft::UI::Xaml::Navigation::NavigationEventArgs const& e)
{
	auto propertyValue{ e.Parameter().as<Windows::Foundation::IPropertyValue>() };
	if (propertyValue.Type() == Windows::Foundation::PropertyType::String)
	{
		auto name{ winrt::unbox_value<winrt::hstring>(e.Parameter()) };
		if (!name.empty())
		{
			greeting().Text(L"Hello, " + name);
			__super::OnNavigatedTo(e);
			return;
		}
	}
	greeting().Text(L"Hello!");
	__super::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.

Lorsque l’événement Click de dans MainPageHyperlinkButton appelle Frame.Navigate(typeof(Page2), name.Text), la name.Text propriété est passée à Page2et la valeur des données d’événement est utilisée pour le message affiché sur la page.

5. Mettre en cache une 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.

Dans notre exemple d’égal à égal de base, lorsque vous cliquez sur le Click to go to page 1 lien sur Page2, le TextBox (et tout autre champ) activé est défini sur MainPage son état par défaut. 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.

Par défaut, une nouvelle page instance est créée avec ses valeurs par défaut chaque fois que la navigation se produit. Dans MainPage.xaml, définissez EnabledNavigationCacheMode sur (dans la balise d’ouverturePage) pour mettre en cache la page et conserver toutes les valeurs de contenu et d’état de la page jusqu’à ce que le cache de page pour le cadre soit dépassé. 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. Toutefois, n’oubliez pas que la taille limite du cache peut être cruciale, selon les limites de mémoire d’un appareil.

<Page
    x:Class="BasicNavigation.MainPage"
    ...
    mc:Ignorable="d"
    NavigationCacheMode="Enabled">

À présent, lorsque vous revenez à main page, le nom que vous avez entré dans la zone de texte est toujours là.

6. Personnaliser les animations de transition de page

Par défaut, chaque page est animée dans le cadre lorsque la navigation se produit. L’animation par défaut est une animation « entrée » qui fait glisser la page vers le haut à partir du bas de la fenêtre. Toutefois, vous pouvez choisir différentes options d’animation qui conviennent mieux à la navigation de votre application. Par exemple, vous pouvez utiliser une animation « d’exploration » pour donner l’impression que l’utilisateur va plus loin dans votre application, ou une animation de diapositive horizontale pour donner l’impression que deux pages sont des homologues. Pour plus d’informations, consultez Transitions de page.

Ces animations sont représentées par des sous-classes de NavigationTransitionInfo. Pour spécifier l’animation à utiliser pour une transition de page, vous allez utiliser la troisième surcharge de la Navigate méthode et passer une NavigationTransitionInfo sous-classe comme troisième paramètre (infoOverride). Voici la signature de cette Navigate surcharge :

public bool Navigate(System.Type sourcePageType, 
                     object parameter,
                     NavigationTransitionInfo infoOverride);
bool Navigate(TypeName const& sourcePageType, 
              IInspectable const& parameter, 
              NavigationTransitionInfo const& infoOverride);

Dans le HyperlinkButton_Click gestionnaire d’événements du MainPage fichier code-behind, ajoutez un troisième paramètre à la Navigate méthode qui définit le infoOverride paramètre sur un SlideNavigationTransitionInfo avec sa propriété Effect définie sur FromRight.

// MainPage.xaml.cs

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    Frame.Navigate(typeof(Page2), 
                   name.Text,
                   new SlideNavigationTransitionInfo() 
                       { Effect = SlideNavigationTransitionEffect.FromRight});
}
// pch.h

#include <winrt/Microsoft.UI.Xaml.Media.Animation.h>

////////////////////
// MainPage.xaml.cpp

using namespace winrt::Microsoft::UI::Xaml::Media::Animation;

// ...

void winrt::BasicNavigation::implementation::MainPage::HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{   
    // Create the slide transition and set the transition effect to FromRight.
    SlideNavigationTransitionInfo slideEffect = SlideNavigationTransitionInfo();
    slideEffect.Effect(SlideNavigationTransitionEffect(SlideNavigationTransitionEffect::FromRight));
    Frame().Navigate(winrt::xaml_typename<BasicNavigation::Page2>(),
        		     winrt::box_value(name().Text()),
                     slideEffect);
}

Dans le HyperlinkButton_Click gestionnaire d’événements du Page2 fichier code-behind, définissez le infoOverride paramètre sur un SlideNavigationTransitionInfo avec sa propriété Effect définie sur FromLeft.

// Page2.xaml.cs

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
    Frame.Navigate(typeof(MainPage),
                   null,
                   new SlideNavigationTransitionInfo() 
                       { Effect = SlideNavigationTransitionEffect.FromLeft});
}
// Page2.xaml.cpp

using namespace winrt::Microsoft::UI::Xaml::Media::Animation;

// ...

void winrt::BasicNavigation::implementation::MainPage::HyperlinkButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{   
    // Create the slide transition and set the transition effect to FromLeft.
    SlideNavigationTransitionInfo slideEffect = SlideNavigationTransitionInfo();
    slideEffect.Effect(SlideNavigationTransitionEffect(SlideNavigationTransitionEffect::FromLeft));
    Frame().Navigate(winrt::xaml_typename<BasicNavigation::MainPage>(),
        		     nullptr,
                     slideEffect);
}

Maintenant, lorsque vous naviguez entre les pages, les pages glissent vers la gauche et la droite, ce qui procure une sensation plus naturelle pour cette transition et renforce la connexion entre les pages.