Implementare lo spostamento tra due pagine
Scopri come usare un frame e le pagine per abilitare lo spostamento peer-to-peer di base nell'app.
Quasi ogni app richiede lo spostamento tra le pagine. Anche un'app semplice con una singola pagina di contenuto avrà in genere una pagina di impostazioni che richiede la navigazione. In questo articolo vengono descritti i concetti di base dell'aggiunta di un codice XAML Page
all'app e l'uso di un Frame
oggetto per spostarsi tra le pagine.
Importante
Per questo esempio viene usato il modello App vuota di Microsoft Visual Studio. Esistono differenze nei modelli per le app SDK per app di Windows/WinUI 3 e le app UWP, quindi assicurati di selezionare la scheda corretta per il tipo di app.
- Si applica a: SDK per app di Windows/WinUI3
- API importanti: classe Microsoft.UI.Xaml.Controls.Frame, classe Microsoft.UI.Xaml.Controls.Page, spazio dei nomi Microsoft.UI.Xaml.Navigation
1. Creare un'app vuota
Per creare un'app vuota in Visual Studio:
- Per configurare il computer di sviluppo, consultare Installare gli strumenti per Windows App SDK.
- Nella finestra iniziale di Microsoft Visual Studio selezionare Crea un nuovo progetto oppure scegliere File>nuovo>progetto dal menu di Visual Studio.
- Nella finestra di dialogo Crea un nuovo progetto selezionare C# oppure C++ rispettivamente Windows e WinUI.
- Seleziona il modello del progetto Blank App, Packaged (WinUI 3 in Desktop) e fai clic su Avanti. Questo modello crea un'app desktop con un'interfaccia utente basata su WinUI 3.
- In Nome progetto, inserire
BasicNavigation
e fare clic su Crea. - Per eseguire il programma, scegliere Debug>Avvia debug dal menù, oppure premere F5. Compilare ed eseguire la soluzione sul computer di sviluppo per verificare che l'app venga eseguita senza errori. Viene visualizzata una pagina vuota.
- Per arrestare il debug e tornare a Visual Studio, chiudi l'app o scegli Arresta debug dal menu.
- Rimuovere qualsiasi codice di esempio incluso nel modello dai
MainWindow.xaml
file code-behind eMainWindow
.
Suggerimento
Per altre info, vedi Creare il primo progetto WinUI 3 (SDK per app di Windows).
2. Utilizzare un frame per spostarsi tra le pagine
Quando l'app ha più pagine, usa un frame per spostarsi tra di loro. La Frame
classe supporta diversi metodi di spostamento come Navigate, GoBack e GoForward e proprietà come BackStack, ForwardStack e BackStackDepth.
Quando si crea un nuovo progetto SDK per app di Windows in Visual Studio, il modello di progetto crea una MainWindow
classe (di tipo Microsoft.UI.Xaml.Window). Tuttavia, non crea un frame o una pagina e non fornisce alcun codice di spostamento.
Per abilitare lo spostamento tra le pagine, aggiungere un Frame
oggetto come elemento radice di MainWindow
. A tale scopo, è possibile eseguire l'override del metodo Application.OnLaunched nel App.xaml
file code-behind. Aprire il App
file code-behind, aggiornare l'override OnLaunched
e gestire l'evento NavigationFailed , come illustrato di seguito.
// 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
Per le app con una struttura di spostamento più complessa, in genere userai navigationView come radice di MainWindow e posiziona un Frame
oggetto come contenuto della visualizzazione di spostamento. Per altre informazioni, vedere Navigazione.
Il metodo Navigate viene usato per visualizzare il contenuto in questo Frame
oggetto . In questo caso, MainPage.xaml
viene passato al Navigate
metodo , quindi il metodo viene caricato MainPage
in Frame
.
Se la navigazione alla finestra iniziale dell'app ha esito negativo, si verifica un NavigationFailed
evento e questo codice genera un'eccezione nel gestore eventi.
3. Aggiungere pagine di base
Il modello App vuota non crea automaticamente più pagine dell'app. Prima di poter spostarsi tra le pagine, è necessario aggiungere alcune pagine all'app.
Per aggiungere un nuovo elemento all'app:
- In Esplora soluzioni, fare clic con il pulsante destro del mouse sul
BasicNavigation
progetto FleetManagementClassProject. - Scegli Aggiungi>nuovo elemento dal menu di scelta rapida.
- Nella finestra di dialogo Aggiungi nuovo elemento selezionare il nodo WinUI nel riquadro sinistro, quindi scegliere Pagina vuota (WinUI 3) nel riquadro centrale.
- Nella casella Nome immettere
MainPage
e premere il pulsante Aggiungi. - Ripetere i passaggi da 1 a 4 per aggiungere la seconda pagina, ma nella casella Nome immettere
Page2
.
Questi file dovrebbero ora essere elencati come parte del progetto BasicNavigation
.
C# | C++ |
---|---|
|
|
Importante
Per i progetti C++, è necessario aggiungere una #include
direttiva nel file di intestazione di ogni pagina che fa riferimento a un'altra pagina. Per l'esempio di spostamento tra pagine presentato qui, il file mainpage.xaml.h contiene #include "Page2.xaml.h"
a sua volta page2.xaml.h contiene #include "MainPage.xaml.h"
.
I modelli di pagina C++ includono anche un esempio Button
e un codice del gestore clic che dovrai rimuovere dai file XAML e code-behind per la pagina.
Aggiungere contenuto alle pagine
In MainPage.xaml
, sostituisci il contenuto della pagina esistente con il seguente contenuto:
<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>
Questo codice XAML aggiunge:
- Elemento TextBlock denominato
pageTitle
con la relativa proprietà Text impostata suMain Page
come elemento figlio dell'oggetto Grid radice . - Elemento HyperlinkButton utilizzato per passare alla pagina successiva come elemento figlio della griglia radice .
Nel MainPage
file code-behind, aggiungere il codice seguente per gestire Click
l'evento HyperlinkButton aggiunto per abilitare la navigazione 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
è una sottoclasse della classe Page. La Page
classe ha una proprietà Frame di sola lettura che ottiene Frame
che contiene Page
. Quando il Click
gestore eventi di HyperlinkButton
in MainPage
chiama Frame.Navigate(typeof(Page2))
, Frame
visualizza il contenuto di Page2.xaml
.
Ogni volta che una pagina viene caricata nel frame, viene aggiunta come PageStackEntry all'elemento BackStack o ForwardStack di Frame, consentendo la cronologia di spostamento e lo spostamento indietro.
Eseguire ora la stessa operazione in Page2.xaml
. Sostituisci il contenuto della pagina esistente con il seguente contenuto:
<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>
Nel Page2
file code-behind, aggiungere il seguente codice per gestire Click
l'evento HyperlinkButton per navigare 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>());
}
Compilare ed eseguire l'app. Fare clic sul collegamento "Fare clic per passare alla pagina 2". La seconda pagina che indica "Pagina 2" nella parte superiore deve essere caricata e visualizzata nella cornice. Fare clic sul collegamento nella pagina 2 per tornare alla pagina principale.
4. Passare le informazioni tra le pagine
L'app ora si sposta tra due pagine, ma non fa ancora nulla di interessante. Spesso, quando un'app ha più pagine, le pagine devono condividere informazioni. Ora passerai alcune informazioni dalla prima alla seconda pagina.
In MainPage.xaml
sostituire l'oggetto HyperlinkButton
aggiunto in precedenza con l'oggetto StackPanel seguente . In questo modo viene aggiunta un'etichetta TextBlock e un controllo TextBox name
per l'immissione di una stringa di testo.
<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>
A questo punto si userà il secondo overload del Navigate
metodo e si passerà il testo dalla casella di testo come secondo parametro. Ecco la firma di questo Navigate
overload:
public bool Navigate(System.Type sourcePageType, object parameter);
bool Navigate(TypeName const& sourcePageType, IInspectable const& parameter);
Nel HyperlinkButton_Click
gestore dell'evento del MainPage
file code-behind, aggiungere un secondo parametro al Navigate
metodo che fa riferimento alla Text
proprietà della name
casella di testo.
// 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()));
}
In Page2.xaml
sostituire HyperlinkButton
aggiunto in precedenza con il seguente StackPanel
. Ciò aggiunge TextBlock per la visualizzazione della stringa di testo passata da MainPage
.
<StackPanel VerticalAlignment="Center">
<TextBlock HorizontalAlignment="Center" x:Name="greeting"/>
<HyperlinkButton Content="Click to go to page 1"
Click="HyperlinkButton_Click"
HorizontalAlignment="Center"/>
</StackPanel>
Nel Page2
file code-behind, aggiungere il seguente codice per eseguire l'override del metodo OnNavigatedTo
:
// 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);
}
Eseguire l'app, digitare il nome nella casella di testo e quindi fare clic sul collegamento che indica Click to go to page 2
.
Quando l'evento Click
di HyperlinkButton
in MainPage
chiama Frame.Navigate(typeof(Page2), name.Text)
, la proprietà name.Text
viene passata a Page2
e il valore dei dati dell'evento viene usato per il messaggio visualizzato nella pagina.
5. Memorizzare nella cache una pagina
Per impostazione predefinita, il contenuto e lo stato delle pagine non vengono memorizzati nella cache: per memorizzare informazioni nella cache, devi abilitare questa funzionalità in ogni pagina dell'app.
Nell'esempio peer-to-peer di base, quando si fa clic sul Click to go to page 1
collegamento in Page2
, l'oggetto TextBox
(e qualsiasi altro campo) MainPage
in viene impostato sullo stato predefinito. Un modo per risolvere questo problema consiste nell'usare la proprietà NavigationCacheMode per specificare che una pagina deve essere aggiunta alla cache delle pagine del frame.
Per impostazione predefinita, viene creata una nuova istanza di pagina con i relativi valori predefiniti ogni volta che si verifica lo spostamento. In MainPage.xaml
impostare su NavigationCacheMode
Enabled
(nel tag di apertura Page
) per memorizzare nella cache la pagina e conservare tutti i valori di contenuto e stato per la pagina fino a quando non viene superata la cache della pagina per il frame. Imposta NavigationCacheMode su Required se vuoi ignorare i limiti definiti con CacheSize, che specifica il numero di pagine nella cronologia di spostamento che possono essere memorizzate nella cache per il frame. Tieni tuttavia presente che i limiti relativi alle dimensioni della cache potrebbero essere cruciali, a seconda dei limiti di memoria di un dispositivo.
<Page
x:Class="BasicNavigation.MainPage"
...
mc:Ignorable="d"
NavigationCacheMode="Enabled">
Ora, quando si fa clic di nuovo sulla pagina principale, il nome immesso nella casella di testo è ancora presente.
6. Personalizzare le animazioni di transizione di pagina
Per impostazione predefinita, ogni pagina viene animata nel frame quando si verifica la navigazione. L'animazione predefinita è un'animazione "entrata" che fa scorrere la pagina verso l'alto dalla parte inferiore della finestra. Tuttavia, puoi scegliere diverse opzioni di animazione che meglio si adattano allo spostamento della tua app. Ad esempio, puoi usare un'animazione "drill-in" per dare la sensazione che l'utente stia andando più in profondità nella tua app o un'animazione diapositiva orizzontale per dare la sensazione che due pagine siano peer. Per altre info, vedi Transizioni di pagina.
Queste animazioni sono rappresentate da sottoclassi di NavigationTransitionInfo. Per specificare l'animazione da usare per una transizione di pagina, userai il terzo overload del Navigate
metodo e passerai una NavigationTransitionInfo
sottoclasse come terzo parametro (infoOverride
). Ecco la firma di questo Navigate
overload:
public bool Navigate(System.Type sourcePageType,
object parameter,
NavigationTransitionInfo infoOverride);
bool Navigate(TypeName const& sourcePageType,
IInspectable const& parameter,
NavigationTransitionInfo const& infoOverride);
Nel HyperlinkButton_Click
gestore eventi del MainPage
file code-behind aggiungere un terzo parametro al Navigate
metodo che imposta il infoOverride
parametro su slideNavigationTransitionInfo con la relativa proprietà Effect impostata su 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);
}
Nel HyperlinkButton_Click
gestore eventi del Page2
file code-behind impostare il infoOverride
parametro su SlideNavigationTransitionInfo con la relativa proprietà Effect impostata su 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);
}
Ora, quando si passa da una pagina all'altra, la diapositiva delle pagine verso sinistra e destra, che offre una sensazione più naturale per questa transizione e rafforza la connessione tra le pagine.