NavigationPage

.NET MAUI NavigationPage.

.NET Multi-Platform App UI (.NET MAUI) NavigationPage は、ユーザーが希望どおりにページを前後に移動することができる階層ナビゲーション エクスペリエンスを提供します。 NavigationPage は、Page オブジェクトの後入れ先出し (LIFO) スタックとしてナビゲーションを提供します。

NavigationPage は次の特性を定義します。

  • Brush 型の BarBackground は、ナビゲーション バーの背景を Brush で指定します。
  • Color 型の BarBackgroundColor は、ナビゲーション バーの背景色を指定します。
  • string 型の BackButtonTitle は、[戻る] ボタンに使用するテキストを表します。 これは添付プロパティです。
  • Color 型の BarTextColor は、ナビゲーション バーのテキストの色を指定します。
  • Page 型の CurrentPage は、ナビゲーション スタックの上部にあるページを表します。 これは、読み取り専用プロパティです。
  • bool 型の HasNavigationBar は、NavigationPage にナビゲーション バーがあるかどうかを表します。 このプロパティの既定値は true です。 これは添付プロパティです。
  • bool 型の HasBackButton は、ナビゲーション バーに戻るボタンを含むかどうかを表します。 このプロパティの既定値は true です。 これは添付プロパティです。
  • Color 型の IconColor は、ナビゲーション バーのアイコンの背景色を定義します。 これは添付プロパティです。
  • Page 型の RootPage は、ナビゲーション スタックのルート ページを表します。 これは、読み取り専用プロパティです。
  • ImageSource 型の TitleIconImageSource は、ナビゲーション バーのタイトルを表すアイコンを定義します。 これは添付プロパティです。
  • View 型の TitleView は、ナビゲーション バーに表示できるビューを定義します。 これは添付プロパティです。

これらのプロパティは、BindableProperty オブジェクトが基になっています。つまり、これらは、データ バインディングの対象にすることができ、スタイルを設定できます。

NavigationPage クラスには、次の 3 つのイベントも定義されています。

  • Pushed は、ページがナビゲーション スタックにプッシュされたときに発生します。
  • Popped は、ナビゲーション スタックからページがポップされたときに発生します。
  • PoppedToRoot は、最後のルート以外のページがナビゲーション スタックからポップされたときに発生します。

3 つのイベントはすべて、読み取り専用の Page プロパティを定義する NavigationEventArgs オブジェクトを受け取り、ナビゲーション スタックからポップされたページ、またはスタック上に新しく表示されたページを取得します。

警告

NavigationPage は .NET MAUI シェル アプリと互換性がありません。シェル アプリで NavigationPage を使用しようとすると例外がスローされます。 シェル アプリの詳細については、「シェル」をご覧ください。

モードレス ナビゲーションを実行する

.NET MAUI では、モードレス ページ ナビゲーションがサポートされています。 モードレス ページは画面にとどまり、別のページに移動するまで表示されます。

NavigationPage は通常、ContentPage オブジェクトのスタック内を移動するために使用されます。 あるページから別のページに移動すると、新しいページがスタックにプッシュされ、アクティブなページになります。

Pushing a page to the navigation stack.

2 番目のページから最初のページに戻ると、ページがスタックからポップされ、新しい一番上のページがアクティブになります。

Popping a page from the navigation stack.

NavigationPage はナビゲーション バーで構成され、アクティブなページはナビゲーション バーの下に表示されます。 次の図は、ナビゲーション バーの主要なコンポーネントを示しています。

NavigationPage components.

オプションのアイコンは、[戻る] ボタンと [タイトル] の間に表示できます。

ナビゲーション メソッドは、任意の Page 派生型の Navigation プロパティによって公開されます。 これらのメソッドには、ページをナビゲーション スタックにプッシュする機能、スタックからページをポップする機能、スタックを操作する機能があります。

ヒント

NavigationPageContentPage オブジェクトのみで作成することをお勧めします。

ルート ページを作成する

複数のページを中心に構成されたアプリには、常にルート ページがあります。ルート ページは、ナビゲーション スタックに追加される最初のページです。 これを行うには、コンストラクター引数がアプリのルート ページである NavigationPage オブジェクトを作成し、結果のオブジェクトを App.MainPage プロパティの値として設定します。

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
        MainPage = new NavigationPage(new MainPage());
    }
}

Note

NavigationPageRootPage プロパティは、ナビゲーション スタックにおける最初のページへのアクセスを提供します。

ナビゲーション スタックにページをプッシュ

現在のページの Navigation プロパティで PushAsync メソッドを呼び出すと、ページを移動できます。

await Navigation.PushAsync(new DetailsPage());

この例では、DetailsPage オブジェクトがナビゲーション スタックにプッシュされ、そこでアクティブ ページになります。

Note

PushAsync メソッドには、bool 引数を含むオーバーライドがあります。この引数は、ナビゲーション中にページ切り替えを表示するかどうかを指定します。 bool 引数がない PushAsync メソッドを使用すると、デフォルトでページ切り替えが有効になります。

ナビゲーション スタックからページをポップ

デバイス上の物理的なボタンであるか画面上のボタンであるかにかかわらず、デバイスの [戻る] ボタンを押して、アクティブ ページをナビゲーション スタックからポップできます。

プログラムによって前のページに戻るには、現在のページの Navigation プロパティで PopAsync メソッドを呼び出す必要があります。

await Navigation.PopAsync();

この例では、現在のページがナビゲーション スタックから削除され、一番上の新しいページがアクティブ ページになります。

Note

PopAsync メソッドには、bool 引数を含むオーバーライドがあります。この引数は、ナビゲーション中にページ切り替えを表示するかどうかを指定します。 bool 引数がない PopAsync メソッドを使用すると、デフォルトでページ切り替えが有効になります。

さらに、各ページの Navigation プロパティでは、ルート ページ以外のすべてのページをナビゲーション スタックからポップする PopToRootAsync メソッドも公開されるため、アプリのルート ページがアクティブ ページになります。

ナビゲーション スタックの操作

PageNavigation プロパティでは、ナビゲーション スタックのページを取得できる NavigationStack プロパティが公開されます。 .NET MAUI はナビゲーション スタックへのアクセスを維持しますが、Navigation プロパティには、ページを挿入または削除してスタックを操作するための InsertPageBefore メソッドと RemovePage メソッドが用意されています。

次の図に示すように、InsertPageBefore メソッドによって、ナビゲーション スタック内の指定されたページが既存の指定されたページの前に挿入されます。

Inserting a page in the navigation stack.

次の図に示すように、RemovePage メソッドによって、指定されたページがナビゲーション スタックから削除されます。

Removing a page from the navigation stack.

これらのメソッドを使用すると、ログインに成功した後に、ログイン ページを新しいページに置き換えるなど、カスタムのナビゲーション エクスペリエンスを実現できます。

モーダル ナビゲーションの実行

.NET MAUI では、モーダル ページ ナビゲーションがサポートされています。 モーダル ページは、そのタスクが完了するかキャンセルされるまで、他の操作ができない自己完結型のタスクを完了させるようユーザーに促します。

モーダル ページには、.NET MAUI でサポートされている任意のページ タイプを使用できます。 ページをモーダルで表示するには、アプリでそのページをモーダル スタックにプッシュします。すると、そのページはアクティブ ページになります。

Pushing a page to the modal stack.

前のページに戻るには、アプリでモーダル スタックから現在のページをポップする必要があります。すると、一番上の新しいページがアクティブ ページになります。

Popping a page from the modal stack.

モーダル ナビゲーション メソッドは、任意の Page 派生型の Navigation プロパティによって公開されます。 これらのメソッドは、モーダル スタックにページをプッシュしたり、モーダル スタックからページをポップしたりする機能を提供します。 Navigation プロパティでは、モーダル スタックのページを取得する ModalStack プロパティも公開されます。 ただし、モーダル スタックの操作を実行したり、モーダル ナビゲーションで、ルート ページにポップしたりする概念はありません。 これは、これらの操作が基になるプラットフォームで一般にサポートされていないためです。

Note

NavigationPage オブジェクトは、モーダル ページ ナビゲーションの実行には必要ありません。

モーダル スタックにページをプッシュ

現在のページの Navigation プロパティで PushModalAsync メソッドを呼び出すことで、ページをモーダルで移動できます。

await Navigation.PushModalAsync(new DetailsPage());

この例では、DetailsPage オブジェクトがモーダル スタックにプッシュされ、アクティブ ページになります。

Note

PushModalAsync メソッドには、bool 引数を含むオーバーライドがあります。この引数は、ナビゲーション中にページ切り替えを表示するかどうかを指定します。 bool 引数がない PushModalAsync メソッドを使用すると、デフォルトでページ切り替えが有効になります。

モーダル スタックからページをポップ

デバイス上の物理的なボタンであるか画面上のボタンであるかにかかわらず、デバイスの [戻る] ボタンを押して、アクティブ ページをモーダル スタックからポップできます。

プログラムによって元のページに戻るには、現在のページの Navigation プロパティで PopModalAsync メソッドを呼び出す必要があります。

await Navigation.PopModalAsync();

この例では、現在のページがモーダル スタックから削除され、一番上の新しいページがアクティブ ページになります。

Note

PopModalAsync メソッドには、bool 引数を含むオーバーライドがあります。この引数は、ナビゲーション中にページ切り替えを表示するかどうかを指定します。 bool 引数がない PopModalAsync メソッドを使用すると、デフォルトでページ切り替えが有効になります。

[戻る] ボタンを無効にする

Android では、デバイスの標準の [戻る] ボタンを押して、いつでも前のページに戻ることができます。 モーダル ページで、ユーザーがページから離れる前に自己完結型タスクを完了する必要がある場合は、アプリケーションで [戻る] ボタンを無効にする必要があります。 これを実現するには、モーダル ページの Page.OnBackButtonPressed メソッドをオーバーライドします。

ナビゲーション中にデータを渡す

場合によっては、ナビゲーション中に、あるページから別のページにデータを渡す必要があります。 これを実現する 2 つの手法は、ページ コンストラクターを介してデータを渡すことと、新しいページの BindingContext をデータに設定することです。

ページ コンストラクターを介してデータを渡す

ナビゲーション中に別のページにデータを渡す最も簡単な手法は、ページ コンストラクター引数を使用することです。

Contact contact = new Contact
{
    Name = "Jane Doe",
    Age = 30,
    Occupation = "Developer",
    Country = "USA"
};
...
await Navigation.PushModalAsync(new DetailsPage(contact));

この例では、Contact オブジェクトはコンストラクター引数として DetailPage に渡されます。 その後、Contact オブジェクトを DetailsPage で表示できます。

BindingContext を介してデータを渡す

ナビゲーション中に別のページにデータを渡すもう 1 つの方法は、新しいページの BindingContext をデータに設定することです。

Contact contact = new Contact
{
    Name = "Jane Doe",
    Age = 30,
    Occupation = "Developer",
    Country = "USA"
};

await Navigation.PushAsync(new DetailsPage
{
    BindingContext = contact  
});

ページの BindingContext を介してナビゲーション データを渡す利点は、新しいページでデータ バインディングを使用してデータを表示できることです。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyMauiApp.DetailsPage"
             Title="Details">
    <StackLayout>
        <Label Text="{Binding Name}" />
        <Label Text="{Binding Occupation}" />
    </StackLayout>
</ContentPage>

データ バインディングの詳細については、「データ バインディング」をご覧ください。

ナビゲーション バーにビューを表示する

すべての .NET MAUI View は、NavigationPage のナビゲーション バーに表示できます。 これを実現するには、NavigationPage.TitleView 添付プロパティを View に設定します。 この添付プロパティは任意の Page に設定できます。また、PageNavigationPage にプッシュされると、NavigationPage ではプロパティの値が反映されます。

次の例では、NavigationPage.TitleView 添付プロパティを設定する方法を示します。

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="NavigationPageTitleView.TitleViewPage">
    <NavigationPage.TitleView>
        <Slider HeightRequest="44"
                WidthRequest="300" />
    </NavigationPage.TitleView>
    ...
</ContentPage>

同等の C# コードを次に示します。

Slider titleView = new Slider { HeightRequest = 44, WidthRequest = 300 };
NavigationPage.SetTitleView(this, titleView);

この例では、ズームを制御するために、SliderNavigationPage のナビゲーション バーに表示されます。

重要

ビューのサイズが WidthRequest およびHeightRequest のプロパティで指定されていない場合、多くのビューはナビゲーション バーに表示されません。

Layout クラスは View クラスから派生しているため、複数のビューを含むレイアウト クラスを表示するように TitleView 添付プロパティを設定することができます。 ただし、ナビゲーション バーに表示されるビューがナビゲーション バーの既定のサイズより大きい場合は、クリッピングが発生する可能性があります。 一方 Android では、NavigationPage.BarHeight バインディング可能プロパティを新しい高さを表す double に設定することで、ナビゲーション バーの高さを変更できます。

また、ナビゲーション バーにコンテンツの一部を配置し、ナビゲーション バーと色を合わせたビューの一部をページ コンテンツの上部に配置して、拡張ナビゲーション バーを提案することもできます。 さらに、iOS では、NavigationPage.HideNavigationBarSeparator バインド可能プロパティを true に設定することで、ナビゲーション バーの下部にあるセパレーターと影を削除できます。

ヒント

BackButtonTitleTitleTitleIconImageSourceTitleView のプロパティのいずれでも、ナビゲーション バー上の領域を占める値を定義できます。 ナビゲーション バーのサイズはプラットフォームや画面サイズによって変わりますが、これらのプロパティをすべて設定すると、領域が限られているために競合が発生します。 これらのプロパティの組み合わせを使用するのではなく、TitleView プロパティのみ設定して目的のナビゲーション バーのデザインを改善することをお勧めします。