.NET Multi-platform App UI (.NET MAUI) NavigationPage は、ユーザーが前後に目的のページに移動することができる階層ナビゲーション エクスペリエンスを提供します。 NavigationPage は、Page オブジェクトの後入れ先出し (LIFO) スタックとしてナビゲーションを提供します。
NavigationPage には、次のプロパティが定義されています。
-
BarBackground型の Brush は、Brush としてナビゲーション バーの背景を指定します。 -
BarBackgroundColor型の Color は、ナビゲーション バーの背景色を指定します。 -
BackButtonTitle型のstringは、[戻る] ボタンに使用されるテキストを表します。 これは添付プロパティです。 -
BarTextColor型の Color は、ナビゲーション バーのテキストの色を指定します。 -
CurrentPage型の Page は、ナビゲーション スタックの上部にあるページを表します。 これは、読み取り専用プロパティです。 -
HasNavigationBar型のboolは、ナビゲーション バーが NavigationPage に存在するかどうかを表します。 このプロパティの既定値はtrueです。 これは添付プロパティです。 -
HasBackButton型のboolは、ナビゲーション バーに [戻る] ボタンが含まれているかどうかを表します。 このプロパティの既定値はtrueです。 これは添付プロパティです。 -
IconColor型の Color は、ナビゲーション バーのアイコンの背景色を定義します。 これは添付プロパティです。 -
RootPage型の Page は、ナビゲーション スタックのルート ページを表します。 これは、読み取り専用プロパティです。 -
TitleIconImageSource型の ImageSource は、ナビゲーション バーのタイトルを表すアイコンを定義します。 これは添付プロパティです。 -
TitleView型の View は、ナビゲーション バーに表示できるビューを定義します。 これは添付プロパティです。
これらのプロパティは、BindableProperty オブジェクトが基になっています。つまり、これらは、データ バインディングの対象にすることができ、スタイルを設定できます。
NavigationPage クラスでは、3 つのイベントも定義します。
-
Pushedは、ページがナビゲーション スタックにプッシュされたときに発生します。 -
Poppedは、ナビゲーション スタックからページがポップされたときに発生します。 -
PoppedToRootは、最後のルート以外のページがナビゲーション スタックからポップされたときに発生します。
3 つのイベントはすべて、読み取り専用 NavigationEventArgs プロパティを定義する Page オブジェクトを受け取ります。このプロパティは、ナビゲーション スタックからポップされたページ、またはスタック上の新しく表示されるページを取得します。
警告
NavigationPage は .NET MAUI Shell アプリと互換性がありません。シェル アプリで NavigationPage を使用しようとすると例外がスローされます。 シェル アプリの詳細については、「シェル」をご覧ください。
モードレス ナビゲーションを実行する
.NET MAUI では、モードレス ページ ナビゲーションがサポートされています。 モードレス ページは画面に表示され、別のページに移動するまで使用できます。
NavigationPage は通常、ContentPage オブジェクトのスタック内を移動するために使用されます。 あるページが別のページに移動すると、新しいページがスタックにプッシュされ、アクティブなページになります。
2 番目のページが最初のページに戻ると、ページがスタックからポップされ、新しい一番上のページがアクティブになります。
NavigationPage はナビゲーション バーで構成され、アクティブなページはナビゲーション バーの下に表示されます。 次の図は、ナビゲーション バーの主要なコンポーネントを示します。
オプションのアイコンは、[戻る] ボタンとタイトルの間に表示できます。
ナビゲーション メソッドは、任意の Navigation 派生型の Page プロパティによって公開されます。 これらのメソッドには、ページをナビゲーション スタックにプッシュし、スタックからページをポップし、スタックを操作する機能があります。
ヒント
NavigationPage に ContentPage オブジェクトのみを入力することをお勧めします。
ルート ページを作成する
複数のページで構成されるアプリには、常にルートページがあります。ルート ページは、ナビゲーション スタックに追加された最初のページです。 これを行うには、コンストラクター引数がアプリのルート ページである 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
RootPage の NavigationPage プロパティは、ナビゲーション スタックにおける最初のページへのアクセスを提供します。
ナビゲーション スタックにページをプッシュする
現在のページの PushAsync プロパティで Navigation メソッドを呼び出すと、ページに移動できます。
await Navigation.PushAsync(new DetailsPage());
この例では、DetailsPage オブジェクトがナビゲーション スタックにプッシュされ、そこでアクティブ ページになります。
Note
PushAsync メソッドには、ナビゲーション中にページ切り替えを表示するかどうかを指定する bool 引数を含むオーバーライドがあります。
PushAsync 引数がない bool メソッドを使用すると、既定でページ切り替えが有効になります。
ナビゲーション スタックからページをポップする
デバイス上の物理的なボタンであるか画面上のボタンであるかにかかわらず、デバイスの [戻る] ボタンを押して、アクティブ ページをナビゲーション スタックからポップできます。
プログラムによって前のページに戻すには、現在のページの PopAsync プロパティで Navigation メソッドを呼び出す必要があります。
await Navigation.PopAsync();
この例では、現在のページがナビゲーション スタックから削除され、新しい一番上のページがアクティブなページになります。
Note
PopAsync メソッドには、ナビゲーション中にページ切り替えを表示するかどうかを指定する bool 引数を含むオーバーライドがあります。
PopAsync 引数がない bool メソッドを使用すると、既定でページ切り替えが有効になります。
さらに、各ページの Navigation プロパティでは、ルート ページ以外のすべてをナビゲーション スタックからポップする PopToRootAsync メソッドも公開されるため、アプリのルート ページがアクティブなページになります。
ナビゲーション スタックを操作する
Navigation の Page プロパティでは、ナビゲーション スタックのページを取得できる NavigationStack プロパティが公開されます。 .NET MAUI はナビゲーション スタックへのアクセスを維持しますが、Navigation プロパティには、ページを挿入または削除してスタックを操作するための InsertPageBefore メソッドと RemovePage メソッドが備わっています。
次の図に示すように、InsertPageBefore メソッドによって、ナビゲーション スタック内の指定されたページが既存の指定されたページの前に挿入されます。
次の図に示すように、RemovePage メソッドによって、指定されたページがナビゲーション スタックから削除されます。
これらのメソッドを使用すると、ログインに成功した後に、ログイン ページを新しいページに置き換えるなど、カスタムのナビゲーション エクスペリエンスを実現できます。
モーダル ナビゲーションを実行する
.NET MAUI では、モーダル ページ ナビゲーションがサポートされています。 モーダル ページは、そのタスクが完了するかキャンセルされるまで、他の操作ができない自己完結型のタスクを完了させるようユーザーに促します。
モーダル ページには、.NET MAUI でサポートされる任意のページ タイプを使用できます。 ページをモーダルで表示するには、アプリでそのページをモーダル スタックにプッシュします。すると、そのページはアクティブ ページになります。
前のページに戻るには、アプリでモーダル スタックから現在のページをポップする必要があります。すると、一番上の新しいページがアクティブ ページになります。
モーダル ナビゲーション メソッドは、任意の Navigation 派生型の Page プロパティによって公開されます。 これらのメソッドは、モーダル スタックにページをプッシュしたり、モーダル スタックからページをポップしたりする機能を提供します。
Navigation プロパティでは、モーダル スタックのページを取得する ModalStack プロパティも公開されます。 ただし、モーダル スタックの操作を実行したり、モーダル ナビゲーションで、ルート ページにポップしたりする概念はありません。 これは、これらの操作が基になるプラットフォームで一般にサポートされていないためです。
Note
NavigationPage オブジェクトは、モーダル ページ ナビゲーションの実行には必要ありません。
モーダル スタックにページをプッシュする
現在のページの PushModalAsync プロパティで Navigation メソッドを呼び出すことによって、ページをモーダルに移動できます。
await Navigation.PushModalAsync(new DetailsPage());
この例では、DetailsPage オブジェクトがモーダル スタックにプッシュされ、アクティブ ページになります。
Note
PushModalAsync メソッドには、ナビゲーション中にページ切り替えを表示するかどうかを指定する bool 引数を含むオーバーライドがあります。
PushModalAsync 引数がない bool メソッドを使用すると、既定でページ切り替えが有効になります。
モーダル スタックからページをポップする
デバイス上の物理的なボタンであるか画面上のボタンであるかにかかわらず、デバイスの [戻る] ボタンを押して、アクティブ ページをモーダル スタックからポップできます。
プログラムによって元のページに戻るには、現在のページの PopModalAsync プロパティで Navigation メソッドを呼び出す必要があります。
await Navigation.PopModalAsync();
この例では、現在のページがモーダル スタックから削除され、一番上の新しいページがアクティブ ページになります。
Note
PopModalAsync メソッドには、ナビゲーション中にページ切り替えを表示するかどうかを指定する bool 引数を含むオーバーライドがあります。
PopModalAsync 引数がない bool メソッドを使用すると、既定でページ切り替えが有効になります。
[戻る] ボタンを無効にする
Android では、デバイスの標準の [戻る] ボタンを押して、いつでも前のページに戻ることができます。 モーダル ページで、ユーザーがページから離れる前に自己完結型タスクを完了する必要がある場合は、アプリケーションで [戻る] ボタンを無効にする必要があります。 これを実現するには、モーダル ページの Page.OnBackButtonPressed メソッドをオーバーライドします。
ページ ナビゲーション イベント
Page クラスは、ページ ナビゲーション中に発生するNavigatedTo、NavigatingFrom、およびNavigatedFromナビゲーション イベントを定義します。
NavigatingFrom イベントは、現在のページから移動しようとしているときに発生します。
NavigatedFrom イベントは、現在のページから移動した後に発生します。
NavigatedTo イベントは、現在のページに移動した後に発生します。
Note
iOS および Mac Catalyst では、ページ間を移動するときにネイティブ アニメーションが完了する前に、これらのイベントを発生させることができます。
NavigatedToEventArgs クラスには、次のプロパティが定義されています。
-
PreviousPageは、 Page型で、移動されたページを表します。 -
NavigationTypeは、 NavigationType型で、発生したナビゲーションの種類を表します。
NavigatingFromEventArgs クラスには、次のプロパティが定義されています。
-
DestinationPageは、 Page型で、移動するページを表します。 -
NavigationTypeは、 NavigationType型で、発生しているナビゲーションの種類を表します。
NavigatedFromEventArgs クラスには、次のプロパティが定義されています。
-
DestinationPageは、 Page型で、移動したページを表します。 -
NavigationTypeは、 NavigationType型で、発生したナビゲーションの種類を表します。
NavigationType列挙型は、次のメンバーを定義します。
-
Pushは、ページがナビゲーション スタックにプッシュされたことを示します。 -
Popは、ナビゲーション スタックからページがポップされたことを示します。 -
PopToRootは、ルート ページを除くすべてのページがナビゲーション スタックからポップされたことを示します。 -
Insert: ページがナビゲーション スタックに挿入されたことを示します。 -
Removeは、ナビゲーション スタックからページが削除されたことを示します。 -
Replaceは、ナビゲーション スタックでページが置き換えられたことを示します。
次の例は、ナビゲーション イベントをサブスクライブする方法を示しています。
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
NavigatedTo += OnNavigatedTo;
NavigatingFrom += OnNavigatingFrom;
NavigatedFrom += OnNavigatedFrom;
}
void OnNavigatedTo(object sender, NavigatedToEventArgs args)
{
// Invoked when the page has been navigated to
}
void OnNavigatingFrom(object sender, NavigatingFromEventArgs args)
{
// Invoked when the page is being navigated away from
}
void OnNavigatedFrom(object sender, NavigatedFromEventArgs args)
{
// Invoked when the page has been navigated away from
}
}
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
NavigatedTo += OnNavigatedTo;
NavigatingFrom += OnNavigatingFrom;
NavigatedFrom += OnNavigatedFrom;
}
void OnNavigatedTo(object sender, NavigatedToEventArgs args)
{
// Invoked when the page has been navigated to
Page? previousPage = args.PreviousPage;
NavigationType navigationType = args.NavigationType;
}
void OnNavigatingFrom(object sender, NavigatingFromEventArgs args)
{
// Invoked when the page is being navigated away from
Page? destinationPage = args.DestinationPage;
NavigationType navigationType = args.NavigationType;
}
void OnNavigatedFrom(object sender, NavigatedFromEventArgs args)
{
// Invoked when the page has been navigated away from
Page? destinationPage = args.DestinationPage;
NavigationType navigationType = args.NavigationType;
}
}
Page派生クラスは、イベントをサブスクライブするのではなく、OnNavigatedTo、OnNavigatingFrom、およびOnNavigatedFromメソッドをオーバーライドできます。
public partial class MainPage : ContentPage
{
protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
base.OnNavigatedTo(args);
// Invoked when the page has been navigated to
}
protected override void OnNavigatingFrom(NavigatingFromEventArgs args)
{
base.OnNavigatingFrom(args);
// Invoked when the page is being navigated away from
}
protected override void OnNavigatedFrom(NavigatedFromEventArgs args)
{
base.OnNavigatedFrom(args);
// Invoked when the page has been navigated away from
}
}
public partial class MainPage : ContentPage
{
protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
base.OnNavigatedTo(args);
// Invoked when the page has been navigated to
Page? previousPage = args.PreviousPage;
NavigationType navigationType = args.NavigationType;
}
protected override void OnNavigatingFrom(NavigatingFromEventArgs args)
{
base.OnNavigatingFrom(args);
// Invoked when the page is being navigated away from
Page? destinationPage = args.DestinationPage;
NavigationType navigationType = args.NavigationType;
}
protected override void OnNavigatedFrom(NavigatedFromEventArgs args)
{
base.OnNavigatedFrom(args);
// Invoked when the page has been navigated away from
Page? destinationPage = args.DestinationPage;
NavigationType navigationType = args.NavigationType;
}
}
これらのメソッドをオーバーライドして、ナビゲーションの直後に作業を実行できます。 たとえば、 OnNavigatedTo メソッドでは、データベースまたは Web サービスから項目のコレクションを設定できます。
ナビゲーション中にデータを渡す
場合によっては、ナビゲーション中に、あるページから別のページにデータを渡す必要があります。 これを実現する 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"
xmlns:local="clr-namespace:MyMauiApp"
x:Class="MyMauiApp.DetailsPage"
Title="Details"
x:DataType="local:Contact">
<StackLayout>
<Label Text="{Binding Name}" />
<Label Text="{Binding Occupation}" />
</StackLayout>
</ContentPage>
データ バインディングの詳細については、「 データ バインディング」をご覧ください。
ナビゲーション バーにビューを表示する
すべての .NET MAUI View は、NavigationPage のナビゲーション バーに表示できます。 これを実現するには、NavigationPage.TitleView 添付プロパティを View に設定します。 この添付プロパティは任意の Page に設定できます。また、Page が NavigationPage にプッシュされると、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);
この例では、ズームを制御するために、Slider が NavigationPage のナビゲーション バーに表示されます。
重要
ビューのサイズが WidthRequest およびHeightRequest のプロパティで指定されていない場合、多くのビューはナビゲーション バーに表示されません。
Layout クラスは View クラスから派生しているため、複数のビューを含むレイアウト クラスを表示するように TitleView 添付プロパティを設定することができます。 ただし、ナビゲーション バーに表示されるビューがナビゲーション バーの既定のサイズより大きい場合は、クリッピングが発生する可能性があります。 一方 Android では、NavigationPage.BarHeight バインディング可能プロパティを新しい高さを表す double に設定することで、ナビゲーション バーの高さを変更できます。
また、ナビゲーション バーにコンテンツの一部を配置し、ナビゲーション バーと色を合わせたビューの一部をページ コンテンツの上部に配置して、拡張ナビゲーション バーを提案することもできます。 さらに、iOS では、NavigationPage.HideNavigationBarSeparator バインド可能プロパティを true に設定することで、ナビゲーション バーの下部にあるセパレーターと影を削除できます。
ヒント
BackButtonTitle、Title、TitleIconImageSource、TitleView のプロパティのいずれでも、ナビゲーション バー上の領域を占める値を定義できます。 ナビゲーション バーのサイズはプラットフォームや画面サイズによって変わりますが、これらのプロパティをすべて設定すると、領域が限られているために競合が発生します。 これらのプロパティの組み合わせを使用するのではなく、TitleView プロパティのみ設定して目的のナビゲーション バーのデザインを改善することをお勧めします。
.NET MAUI