Implementación del desplazamiento entre dos páginas
Aprende a usar un marco y páginas para habilitar la navegación punto a punto básica en una aplicación.
Casi todas las aplicaciones requieren navegación entre páginas. Incluso una aplicación sencilla con una sola página de contenido normalmente tendrá una página de configuración que requiere navegación. En este artículo, se describen los conceptos básicos de agregar un XAML Page
a la aplicación y usar un Frame
para navegar entre páginas.
Importante
Usamos la plantilla Aplicación en blanco de Microsoft Visual Studio para este ejemplo. Existen diferencias en las plantillas para aplicaciones de SDK de Aplicaciones para Windows/WinUI 3 y aplicaciones para UWP, por lo que asegúrate de seleccionar la pestaña correcta para tu tipo de aplicación.
- Se aplica a: SDK de Aplicaciones para Windows/WinUI3
- API importantes: Clase Microsoft.UI.Xaml.Controls.Frame, Microsoft.UI.Xaml.Controls.Page clase, espacio de nombres Microsoft.UI.Xaml.Navigation
1. Crear una aplicación en blanco
Para crear una aplicación en blanco en Visual Studio:
- Para configurar el equipo de desarrollo, consulte Instalación de herramientas para el SDK de Aplicaciones para Windows.
- En la ventana de inicio de Microsoft Visual Studio, seleccione Crear un nuevo proyecto, O bien, en el menú de Visual Studio, elija Archivo>nuevo>proyecto.
- En el cuadro de diálogo Crear un nuevo proyecto , seleccione C# o C++, Windows y WinUI, respectivamente.
- Seleccione la plantilla de proyecto Aplicación vacía, empaquetada (WinUI 3 en escritorio) y haga clic en Siguiente. Esa plantilla crea una aplicación de escritorio con una interfaz de usuario basada en WinUI 3.
- En el cuadro Nombre del proyecto, escriba
BasicNavigation
y haga clic en Crear. - Para ejecutar el programa, elija Depurar Iniciar depuración> en el menú o presione F5. Compile y ejecute la solución en el equipo de desarrollo para confirmar que la aplicación se ejecuta sin errores. Se muestra una página en blanco.
- Para detener la depuración y volver a Visual Studio, sal de la aplicación o haz clic en la opción Detener depuración del menú.
- Quite cualquier código de ejemplo que se incluya en la plantilla de los
MainWindow.xaml
archivos de código subyacente yMainWindow
.
Sugerencia
Para obtener más información, consulta Crear tu primer proyecto de WinUI 3 (SDK de Aplicaciones para Windows).
2. Usar un marco para navegar entre páginas
Cuando la aplicación tiene varias páginas, usa un marco para navegar entre ellas. La Frame
clase admite varios métodos de navegación, como Navigate, GoBack y GoForward, y propiedades como BackStack, ForwardStack y BackStackDepth.
Al crear un nuevo proyecto de SDK de Aplicaciones para Windows en Visual Studio, la plantilla de proyecto crea una MainWindow
clase (de tipo Microsoft.UI.Xaml.Window). Sin embargo, no crea un marco ni una página y no proporciona ningún código de navegación.
Para habilitar la navegación entre páginas, agregue como Frame
elemento raíz de MainWindow
. Puede hacerlo en la invalidación del método Application.OnLaunched en el App.xaml
archivo de código subyacente. Abra el App
archivo de código subyacente, actualice la OnLaunched
invalidación y controle el evento NavigationFailed como se muestra aquí.
// 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);
}
Nota:
En el caso de las aplicaciones con navegación más compleja, normalmente se usa navigationView como raíz de MainWindow y se coloca Frame
como el contenido de la vista de navegación. Para obtener más información, consulta Vista de navegación.
El método Navigate se usa para mostrar contenido en este Frame
. Aquí, MainPage.xaml
se pasa al Navigate
método , por lo que el método se carga MainPage
en .Frame
Si se produce un error en la navegación a la ventana inicial de la aplicación, se produce un NavigationFailed
evento y este código produce una excepción en el controlador de eventos.
3. Agregar páginas básicas
La plantilla Aplicación en blanco no crea varias páginas de aplicación automáticamente. Para poder navegar entre páginas, debe agregar algunas páginas a la aplicación.
Para agregar un nuevo elemento a la aplicación:
- En Explorador de soluciones, haga clic con el botón derecho en el nodo del
BasicNavigation
proyecto para abrir el menú contextual. - Elija Agregar>nuevo elemento en el menú contextual.
- En el cuadro de diálogo Agregar nuevo elemento , seleccione el nodo WinUI en el panel izquierdo y elija Página en blanco (WinUI 3) en el panel central.
- En el cuadro Nombre , escriba
MainPage
y presione el botón Agregar . - Repita los pasos del 1 al 4 para agregar la segunda página, pero en el cuadro Nombre , escriba
Page2
.
Ahora, estos archivos deben aparecer como parte del BasicNavigation
proyecto.
C# | C++ |
---|---|
|
|
Importante
Para los proyectos de C++, debe agregar una #include
directiva en el archivo de encabezado de cada página que haga referencia a otra página. Para el ejemplo de navegación entre páginas que se presenta aquí, el archivo mainpage.xaml.h contiene #include "Page2.xaml.h"
, a su vez, page2.xaml.h contiene #include "MainPage.xaml.h"
.
Las plantillas de página de C++ también incluyen un ejemplo Button
y código de controlador de clics que tendrás que quitar de los archivos XAML y de código subyacente de la página.
Agregar contenido a las páginas
En MainPage.xaml
, reemplace el contenido de la página existente por el siguiente contenido:
<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>
Este XAML agrega:
- Un elemento TextBlock denominado
pageTitle
con su propiedad Text establecidaMain Page
en como elemento secundario de la cuadrícula raíz. - Elemento HyperlinkButton que se usa para navegar a la página siguiente como elemento secundario de la cuadrícula raíz.
En el MainPage
archivo de código subyacente, agregue el código siguiente para controlar el Click
evento de HyperlinkButton que agregó para habilitar la navegación a 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
es una subclase de la clase Page . La Page
clase tiene una propiedad Frame de solo lectura que obtiene el Frame
objeto que contiene .Page
Cuando el Click
controlador de eventos de en HyperlinkButton
MainPage
llama a Frame.Navigate(typeof(Page2))
, Frame
muestra el contenido de Page2.xaml
.
Cada vez que se carga una página en el marco, esa página se agrega como pageStackEntry a BackStack o ForwardStack del marco, lo que permite la navegación del historial y las versiones anteriores.
Ahora, haga lo mismo en Page2.xaml
. Reemplace el contenido de la página existente por el siguiente contenido:
<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>
En el Page2
archivo de código subyacente, agregue el código siguiente para controlar el Click
evento de HyperlinkButton para navegar a 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>());
}
Compile y ejecute la aplicación. Haga clic en el vínculo que dice "Haga clic para ir a la página 2". La segunda página que dice "Página 2" en la parte superior debe cargarse y mostrarse en el marco. Ahora haga clic en el vínculo de la página 2 para volver a la página principal.
4. Pasar información entre páginas
La aplicación ahora navega entre dos páginas, pero realmente no hace nada interesante aún. A menudo, cuando una aplicación tiene varias páginas, las páginas necesitan compartir información. Ahora pasará información de la primera página a la segunda.
En MainPage.xaml
, reemplace el HyperlinkButton
elemento que agregó anteriormente por el siguiente StackPanel. Esto agrega una etiqueta TextBlock y un TextBox name
para escribir una cadena de texto.
<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>
Ahora usará la segunda sobrecarga del Navigate
método y pasará el texto del cuadro de texto como segundo parámetro. Esta es la firma de esta Navigate
sobrecarga:
public bool Navigate(System.Type sourcePageType, object parameter);
bool Navigate(TypeName const& sourcePageType, IInspectable const& parameter);
En el HyperlinkButton_Click
controlador de eventos del MainPage
archivo de código subyacente, agregue un segundo parámetro al método que hace referencia a Navigate
la Text
propiedad del name
cuadro de texto.
// 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()));
}
En Page2.xaml
, reemplace el HyperlinkButton
elemento que agregó anteriormente por el siguiente StackPanel
. Esto agrega un TextBlock para mostrar la cadena de texto pasada desde MainPage
.
<StackPanel VerticalAlignment="Center">
<TextBlock HorizontalAlignment="Center" x:Name="greeting"/>
<HyperlinkButton Content="Click to go to page 1"
Click="HyperlinkButton_Click"
HorizontalAlignment="Center"/>
</StackPanel>
En el Page2
archivo de código subyacente, agregue el código siguiente para invalidar el OnNavigatedTo
método :
// 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);
}
Ejecute la aplicación, escriba el nombre en el cuadro de texto y, a continuación, haga clic en el vínculo que indica Click to go to page 2
.
Cuando el Click
evento de en HyperlinkButton
MainPage
llama Frame.Navigate(typeof(Page2), name.Text)
a , la name.Text
propiedad se pasa a Page2
y el valor de los datos del evento se usa para el mensaje mostrado en la página.
5. Almacenar en caché una página
El contenido y el estado de la página no se almacenan en caché de manera predeterminada, por lo que si quieres almacenar información en la caché, debes habilitar esta opción en todas las páginas de la aplicación.
En nuestro ejemplo básico de punto a punto, al hacer clic en el Click to go to page 1
vínculo de Page2
, el TextBox
(y cualquier otro campo) de MainPage
está establecido en su estado predeterminado. Una manera de solucionar esto es usar la propiedad NavigationCacheMode para especificar que se agregue una página a la memoria caché de páginas del marco.
De forma predeterminada, se crea una nueva instancia de página con sus valores predeterminados cada vez que se produce la navegación. En MainPage.xaml
, establezca en Enabled
NavigationCacheMode
(en la etiqueta de aperturaPage
) para almacenar en caché la página y conservar todos los valores de contenido y estado de la página hasta que se supere la memoria caché de páginas del marco. Establece NavigationCacheMode en Required si quieres ignorar los límites de CacheSize, que especifican el número de páginas en el historial de navegación que pueden almacenarse en la caché para el marco. Sin embargo, no olvides que los límites de tamaño de la caché pueden ser esenciales en función de los límites de memoria de un dispositivo.
<Page
x:Class="BasicNavigation.MainPage"
...
mc:Ignorable="d"
NavigationCacheMode="Enabled">
Ahora, al hacer clic de nuevo en la página principal, el nombre que escribió en el cuadro de texto sigue estando ahí.
6. Personalizar animaciones de transición de página
De forma predeterminada, cada página se anima en el marco cuando se produce la navegación. La animación predeterminada es una animación de "entrada" que hace que la página se deslice hacia arriba desde la parte inferior de la ventana. Sin embargo, puedes elegir diferentes opciones de animación que mejor se adapten a la navegación de tu aplicación. Por ejemplo, puedes usar una animación de "obtención de detalles" para dar la sensación de que el usuario está profundizando en la aplicación o una animación de diapositiva horizontal para dar la sensación de que dos páginas son del mismo nivel. Para obtener más información, consulta Transiciones de página.
Estas animaciones se representan mediante sub clases de NavigationTransitionInfo. Para especificar la animación que se va a usar para una transición de página, usará la tercera sobrecarga del Navigate
método y pasará una NavigationTransitionInfo
subclase como tercer parámetro (infoOverride
). Esta es la firma de esta Navigate
sobrecarga:
public bool Navigate(System.Type sourcePageType,
object parameter,
NavigationTransitionInfo infoOverride);
bool Navigate(TypeName const& sourcePageType,
IInspectable const& parameter,
NavigationTransitionInfo const& infoOverride);
En el HyperlinkButton_Click
controlador de eventos del MainPage
archivo de código subyacente, agregue un tercer parámetro al Navigate
método que establece el infoOverride
parámetro en slideNavigationTransitionInfo con su propiedad Effect establecida en 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);
}
En el HyperlinkButton_Click
controlador de eventos del Page2
archivo de código subyacente, establezca el infoOverride
parámetro en slideNavigationTransitionInfo con su propiedad Effect establecida en 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);
}
Ahora, al navegar entre páginas, las páginas se deslizan a la izquierda y a la derecha, lo que proporciona una sensación más natural para esta transición y refuerza la conexión entre las páginas.
Artículos relacionados
Windows developer