2 ページ間でのナビゲーションを実装する
フレームおよびページを使用した、アプリでの基本的なピア ツー ピアのナビゲーションについて説明します。
ほぼすべてのアプリでページ間のナビゲーションが必要です。 1 つのコンテンツ ページを持つ単純なアプリでも、通常はナビゲーションを必要とする設定ページがあります。 この記事では、アプリに XAML Page
を追加し、 を使用して Frame
ページ間を移動する方法の基本について説明します。
重要
この例では、Microsoft Visual Studio の 空のアプリ テンプレートを使用します。 Windows アプリ SDK/WinUI 3 アプリと UWP アプリのテンプレートには違いがあるため、アプリの種類に適したタブを選択してください。
- 適用対象: Windows アプリ SDK/WinUI3
- 重要な API: Microsoft.UI.Xaml.Controls.Frame クラス、 Microsoft.UI.Xaml.Controls.Page クラス、 Microsoft.UI.Xaml.Navigation 名前空間
1.空のアプリの作成
Visual Studio で空のアプリを作成するには:
- 開発コンピューターをセット アップするには、「Windows App SDK 用のツールをインストールする」を参照してください。
- Microsoft Visual Studio のスタート ウィンドウで、[ 新しいプロジェクトの作成] を選択するか、Visual Studio メニューの [ ファイル>] [新しい>プロジェクト] の順に選択します。
- [ 新しいプロジェクトの作成 ] ダイアログのドロップダウン フィルターで、それぞれ [C# ] または [ C++]、[ Windows]、[ WinUI] を選択します。
- プロジェクト テンプレートとして [空のアプリ、パッケージ (WinUI 3 in Desktop)] を選択し、[次へ] をクリックします。 そのテンプレートで、WinUI 3 ベースのユーザー インターフェイスを使用したデスクトップ アプリが作成されます。
- [ プロジェクト名 ] ボックスに「」と入力
BasicNavigation
し、[ 作成] をクリックします。 - プログラムを実行するには、メニューから [デバッグ]>[デバッグの開始] の順にクリックするか、F5 キーを押します。 開発用コンピューター上でソリューションをビルドして実行し、アプリがエラーなしで動作することを確認します。 空白のページが表示されます。
- デバッグを終了して Visual Studio に戻るには、アプリを終了するか、メニューから [デバッグの停止] クリックします。
- テンプレートに含まれているコード例を、 および
MainWindow
分離コード ファイルからMainWindow.xaml
削除します。
ヒント
詳細については、「初めての WinUI 3 (Windows アプリ SDK) プロジェクトを作成する」を参照してください。
2. フレームを使用してページ間を移動する
アプリに複数のページがある場合は、 Frame を使用してページ間を移動します。 クラスはFrame
、Navigate、GoBack、GoForward などのさまざまなナビゲーション メソッドと、BackStack、ForwardStack、BackStackDepth などのプロパティをサポートしています。
Visual Studio で新しいWindows アプリ SDK プロジェクトを作成すると、プロジェクト テンプレートによって (Microsoft.UI.Xaml.Window 型の) クラスが作成MainWindow
されます。 ただし、 フレーム または ページ は作成せず、ナビゲーション コードも提供しません。
ページ間のナビゲーションを有効にするには、 のMainWindow
ルート要素として を追加Frame
します。 これを行うには、分離コード ファイルの Application.OnLaunched メソッドの App.xaml
オーバーライドを使用します。 分離コード ファイルを App
開き、オーバーライドを OnLaunched
更新し、次に示すように NavigationFailed イベントを処理します。
// 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);
}
Note
より複雑なナビゲーションを使用するアプリの場合は、通常、MainWindow のルートとして NavigationView を使用し、ナビゲーション ビューのコンテンツとして を配置 Frame
します。 詳細については、「 ナビゲーション ビュー」を参照してください。
Navigate メソッドは、この Frame
内のコンテンツを表示するために使用されます。 ここでは、 MainPage.xaml
が メソッドにNavigate
渡されるため、 メソッドは にFrame
読み込まれますMainPage
。
アプリの初期ウィンドウへのナビゲーションが失敗すると、 NavigationFailed
イベントが発生し、このコードはイベント ハンドラーで例外をスローします。
3. 基本ページを追加する
空のアプリ テンプレートでは、複数のアプリ ページは作成されません。 ページ間を移動する前に、いくつかのページをアプリに追加する必要があります。
アプリに新しい項目を追加するには:
- ソリューション エクスプローラーで、プロジェクト ノードを
BasicNavigation
右クリックしてコンテキスト メニューを開きます。 - コンテキスト メニューから [新しい項目の追加]> を選択します。
- [ 新しい項目の追加 ] ダイアログ ボックスで、左側のウィンドウで [WinUI ] ノードを選択し、中央のウィンドウで [空白ページ (WinUI 3)] を選択します。
- [ 名前 ] ボックスに「」と入力
MainPage
し、[ 追加 ] ボタンを押します。 - 手順 1 から 4 を繰り返して 2 番目のページを追加しますが、[ 名前 ] ボックスに「」と入力
Page2
します。
これで、これらのファイルがプロジェクトの BasicNavigation
一部として一覧表示されます。
C# | C++ |
---|---|
|
|
重要
C++ プロジェクトの場合は、別のページを #include
参照する各ページのヘッダー ファイルに ディレクティブを追加する必要があります。 ここで示すページ間ナビゲーションの例では、mainpage.xaml.h ファイルには が含まれています #include "Page2.xaml.h"
。さらに、page2.xaml.h には が #include "MainPage.xaml.h"
含まれています。
C++ ページ テンプレートには、ページの XAML ファイルと分離コード ファイルから削除する必要がある例 Button
とクリック ハンドラー コードも含まれています。
ページにコンテンツを追加する
で MainPage.xaml
、既存のページ コンテンツを次のコンテンツに置き換えます。
<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>
この XAML では、次の項目が追加されます。
- Text プロパティが ルート Grid の子要素として に
Main Page
設定された という名前pageTitle
の TextBlock 要素。 - ルート Grid の子要素として次のページに移動するために使用される HyperlinkButton 要素。
分離コード ファイルで MainPage
、次のコードを追加して、 Click
へのナビゲーションを有効にするために追加した HyperlinkButton のイベントを処理します 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
は Page クラスのサブクラスです。 Page
クラスには、 を含む をFrame
取得する読み取り専用の Frame プロパティがありますPage
。 の Click
MainPage
イベント ハンドラーが をHyperlinkButton
呼び出Frame.Navigate(typeof(Page2))
すと、 Frame
の内容Page2.xaml
が表示されます。
ページがフレームに読み込まれるたびに、そのページは PageStackEntry としてフレームの BackStack または ForwardStack に追加され、履歴と後方ナビゲーションが可能になります。
ここで、 で Page2.xaml
同じ操作を行います。 既存のページ コンテンツを次の内容に置き換えます。
<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>
分離コード ファイルでPage2
、HyperlinkButton のイベントを処理Click
して に移動する次のコードを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>());
}
アプリケーションをビルドし、実行します。 "Click to go to page 2" と書かれているリンクをクリックします。 上部に "Page 2" と書かれた 2 番目のページが読み込まれ、フレームに表示される必要があります。 次に、ページ 2 のリンクをクリックしてメイン ページに戻ります。
4. ページ間で情報を渡す
これで、アプリは 2 つのページ間を移動しますが、まだ興味深いことは何も行われません。 多くの場合、アプリに複数のページがあれば、ページ間で情報を共有する必要があります。 次に、最初のページから 2 番目のページにいくつかの情報を渡します。
で MainPage.xaml
、前に追加した を HyperlinkButton
次の StackPanel に置き換えます。 これにより、テキスト文字列を入力するための TextBlock ラベルと TextBoxname
が追加されます。
<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>
次に、 メソッドの 2 番目のオーバーロードを Navigate
使用し、テキスト ボックスから 2 番目のパラメーターとしてテキストを渡します。 この Navigate
オーバーロードのシグネチャを次に示します。
public bool Navigate(System.Type sourcePageType, object parameter);
bool Navigate(TypeName const& sourcePageType, IInspectable const& parameter);
HyperlinkButton_Click
分離コード ファイルのイベント ハンドラーで、テキスト ボックスの MainPage
プロパティをNavigate
参照する 2 番目のパラメーターを Text
メソッドにname
追加します。
// 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()));
}
で Page2.xaml
、前に追加した HyperlinkButton
を次 StackPanel
の に置き換えます。 これにより、 からMainPage
渡されたテキスト文字列を表示するための TextBlock が追加されます。
<StackPanel VerticalAlignment="Center">
<TextBlock HorizontalAlignment="Center" x:Name="greeting"/>
<HyperlinkButton Content="Click to go to page 1"
Click="HyperlinkButton_Click"
HorizontalAlignment="Center"/>
</StackPanel>
分離コード ファイルで Page2
、次のコードを追加して メソッドを 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);
}
アプリを実行し、テキスト ボックスに自分の名前を入力し、 というリンク Click to go to page 2
をクリックします。
の イベントが Click
を呼び出Frame.Navigate(typeof(Page2), name.Text)
すと、 name.Text
プロパティが にPage2
渡され、イベント データの値がページに表示されるメッセージに使用HyperlinkButton
されます。MainPage
5. ページをキャッシュする
ページのコンテンツと状態は既定ではキャッシュされないため、情報をキャッシュする場合は、アプリの各ページでキャッシュを有効にする必要があります。
基本的なピア ツー ピアの例では、 のリンクPage2
TextBox
をClick to go to page 1
クリックすると、 (およびその他のフィールド) MainPage
が既定の状態に設定されます。 これを回避する方法の 1 つは、NavigationCacheMode プロパティを使って、ページがフレームのページ キャッシュに追加されるように指定することです。
既定では、ナビゲーションが発生するたびに、既定値を使用して新しいページ インスタンスが作成されます。 でMainPage.xaml
、 を (開始Page
タグ内で) にEnabled
設定NavigationCacheMode
してページをキャッシュし、フレームのページ キャッシュを超えるまでページのすべてのコンテンツと状態の値を保持します。 CacheSize の制限を無視する場合は、NavigationCacheMode を Required に設定します。これで、フレームにキャッシュできる、ナビゲーション履歴内のページ数を指定します。 ただし、キャッシュ サイズの制限は、デバイスのメモリの制限に依存しており、重要である可能性があることに注意してください。
<Page
x:Class="BasicNavigation.MainPage"
...
mc:Ignorable="d"
NavigationCacheMode="Enabled">
ここで、メインページに戻ると、テキスト ボックスに入力した名前が表示されます。
6. ページ切り替えアニメーションをカスタマイズする
既定では、ナビゲーションが発生すると、各ページがフレームにアニメーション化されます。 既定のアニメーションは、ウィンドウの下部からページを上にスライドさせる "開始" アニメーションです。 ただし、アプリのナビゲーションに適したさまざまなアニメーション オプションを選択できます。 たとえば、"ドリルイン" アニメーションを使用して、ユーザーがアプリに深く入り込んでいるような感覚を与えたり、水平スライド アニメーションを使用して 2 つのページがピアであるという感覚を与えたりできます。 詳細については、「 ページ切り替え」を参照してください。
これらのアニメーションは、 NavigationTransitionInfo のサブクラスで表されます。 ページ切り替えに使用するアニメーションを指定するには、 メソッドの 3 番目のオーバーロードをNavigate
使用し、3 番目のパラメーター (infoOverride
) としてサブクラスを渡NavigationTransitionInfo
します。 この Navigate
オーバーロードのシグネチャを次に示します。
public bool Navigate(System.Type sourcePageType,
object parameter,
NavigationTransitionInfo infoOverride);
bool Navigate(TypeName const& sourcePageType,
IInspectable const& parameter,
NavigationTransitionInfo const& infoOverride);
分離コード ファイルのHyperlinkButton_Click
MainPage
イベント ハンドラーで、Effect プロパティが FromRight にNavigate
設定された SlideNavigationTransitionInfo にパラメーターを設定infoOverride
する 3 番目のパラメーターを メソッドに追加します。
// 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);
}
HyperlinkButton_Click
分離コード ファイルのPage2
イベント ハンドラーで、 パラメーターを infoOverride
SlideNavigationTransitionInfo に設定し、Effect プロパティを 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);
}
ページ間を移動すると、ページは左右にスライドします。これにより、この切り替えに対してより自然な感覚が得られ、ページ間の接続が強化されます。
関連記事
Windows developer
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示