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

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

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

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

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

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

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

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

NavigationPage コンポーネント。

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

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

ヒント

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

ルート ページを作成する

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

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

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

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
    }

    protected override Window CreateWindow(IActivationState? activationState)
    {
        return new Window(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 メソッドによって、ナビゲーション スタック内の指定されたページが既存の指定されたページの前に挿入されます。

ナビゲーション スタックにページを挿入する。

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

ナビゲーション スタックからページを削除する。

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

モーダル ナビゲーションを実行する

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

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

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

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

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

モーダル ナビゲーション メソッドは、任意の 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 プロパティのみ設定して目的のナビゲーション バーのデザインを改善することをお勧めします。