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 cómo agregar un XAML Page
a la aplicación y usar un Frame
para navegar entre páginas.
Importante
Usamos la plantilla Aplicación vacía de Microsoft Visual Studio para este ejemplo. Hay diferencias en las plantillas para las aplicaciones de SDK de Aplicaciones para Windows/WinUI 3 y las aplicaciones para UWP, así que asegúrate de seleccionar la pestaña correcta para el 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. Creación de una aplicación vacía
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 filtros desplegables, 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, elige Depurar>Iniciar depuración en el menú o presiona F5. Compile y ejecute la solución en el equipo de desarrollo para confirmar que la aplicación se ejecuta sin errores. Aparecerá una página vacía.
- 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, usas 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 o 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 usará navigationView como raíz de MainWindow y colocará como Frame
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 vacía 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, después, elija Página vacía (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 un 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:
- 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 del 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>());
}
El elemento 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 hacia atrás y el historial.
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. Haz clic en el vínculo que dice "Haz clic para ir a la página 2". La segunda página que muestra "Página 2" en la parte superior, se debería cargar y mostrar 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 todavía. 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 TextBoxname
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
objeto 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 su 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 HyperlinkButton
en 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 que se muestra 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 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 este problema es usar la propiedad NavigationCacheMode para especificar que una página se agregue a la memoria caché de la página 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 NavigationCacheMode
Enabled
en (en la etiqueta de apertura Page
) 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 se adapten mejor a la navegación de la 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 más 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
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de