.NET MAUI Shell ナビゲーション
.NET MAUI (.NET マルチプラットフォーム アプリ UI) シェルには、設定されたナビゲーション階層に従わなくても、ルートを使用してアプリ内の任意のページに移動できる URI ベースのナビゲーション エクスペリエンスが含まれています。 さらに、これにより、ナビゲーション スタックのすべてのページにアクセスすることなく、後方に移動する機能も提供されます。
Shell クラスは、次のようなナビゲーション関連のプロパティを定義します。
- BackButtonBehavior: BackButtonBehavior型、戻るボタンの動作を定義する添付プロパティ。
CurrentItem
:ShellItem
型、現在選択されている項目。CurrentPage
: Page 型、現在表示されているページ。CurrentState
:ShellNavigationState
型、Shell の現在のナビゲーションの状態。Current
は、現在のシェルへのアクセスを提供する Shell型の です。
BackButtonBehavior、CurrentItem
、および CurrentState
プロパティは、BindableProperty オブジェクトを基盤としています。つまり、これらのプロパティは、データ バインディングの対象になる場合があります。
ナビゲーションは、Shell クラスから、GoToAsync メソッドを呼び出すことで実行されます。 ナビゲーションが実行されるときに Navigating
イベントが発生し、ナビゲーションが完了するときに Navigated
イベントが発生します。
Note
シェル アプリ内のページ間では、Navigation
プロパティを使用して引き続きナビゲーションを実行できます。 詳細については、「モードレス ナビゲーションを実行する」をご覧ください。
ルート
ナビゲーションは、移動先の URI を指定することによってシェル アプリで実行されます。 ナビゲーション URI には、3 つの要素を含めることができます。
- "ルート"。シェルの視覚階層の一部として存在するコンテンツへのパスを定義します。
- "ページ"。 シェル ビジュアル階層に存在しないページは、シェル アプリ内のどこからでもナビゲーション スタックにプッシュできます。 たとえば、詳細ページは、シェルの視覚階層には定義されませんが、必要に応じてナビゲーション スタック上にプッシュできます。
- 1 つまたは複数の "クエリ パラメーター"。 クエリ パラメーターは、ナビゲーション中に移動先ページに渡すことができるパラメーターです。
ナビゲーション URI に 3 つすべての要素を含めると、構造は //route/page?queryParameters にようになります。
ルートを登録する
ルートは、Route
プロパティを利用して、FlyoutItem、TabBar、Tab、および ShellContent オブジェクトに対して定義できます。
<Shell ...>
<FlyoutItem ...
Route="animals">
<Tab ...
Route="domestic">
<ShellContent ...
Route="cats" />
<ShellContent ...
Route="dogs" />
</Tab>
<ShellContent ...
Route="monkeys" />
<ShellContent ...
Route="elephants" />
<ShellContent ...
Route="bears" />
</FlyoutItem>
<ShellContent ...
Route="about" />
...
</Shell>
Note
シェルの階層内にあるすべての項目には、関連付けられているルートがあります。 ルートを設定しない場合は、実行時に 1 つのルートが生成されます。 ただし、異なるアプリ セッション間で、生成されたルートに一貫性があるという保証はありません。
上の例では、プログラムによるナビゲーションに使用できる次のルート階層を作成します。
animals
domestic
cats
dogs
monkeys
elephants
bears
about
dogs
ルートの ShellContent オブジェクトに移動するには、絶対ルート URI は //animals/domestic/dogs
になります。 同様に、about
ルートの ShellContent オブジェクトに移動するには、絶対ルート URI は //about
になります。
警告
ルートの重複が検出された場合、アプリの起動時に ArgumentException
がスローされます。 この例外は、階層内の同じレベルにある 2 つ以上のルートが 1 つのルート名を共有している場合にもスローされます。
詳細ページ ルートの登録
Shell サブクラス コンストラクター内、またはルートが呼び出される前に実行される他の任意の場所には、シェルの視覚階層に表されない任意の詳細ページへの追加のルートを、明示的に登録できます。 それには Routing.RegisterRoute
メソッドを使います。
Routing.RegisterRoute("monkeydetails", typeof(MonkeyDetailPage));
Routing.RegisterRoute("beardetails", typeof(BearDetailPage));
Routing.RegisterRoute("catdetails", typeof(CatDetailPage));
Routing.RegisterRoute("dogdetails", typeof(DogDetailPage));
Routing.RegisterRoute("elephantdetails", typeof(ElephantDetailPage));
この例では、Shell サブクラスに定義されていない詳細ページを、ルートとして登録します。 これらの詳細ページには、URI ベースのナビゲーションを使用して、アプリ内の任意の場所から移動できます。 このようなページのルートは、"グローバル ルート" と呼ばれます。
警告
Routing.RegisterRoute
メソッドが 2 つ以上の異なる型に同じルートを登録しようとすると、ArgumentException
がスローされます。
または、必要に応じて、別のルート階層にページを登録できます。
Routing.RegisterRoute("monkeys/details", typeof(MonkeyDetailPage));
Routing.RegisterRoute("bears/details", typeof(BearDetailPage));
Routing.RegisterRoute("cats/details", typeof(CatDetailPage));
Routing.RegisterRoute("dogs/details", typeof(DogDetailPage));
Routing.RegisterRoute("elephants/details", typeof(ElephantDetailPage));
この例では、monkeys
ルートのページから details
ルートに移動すると MonkeyDetailPage
が表示される、コンテキストに応じたページ ナビゲーションを実現しています。 同様に、elephants
ルートのページから details
ルートに移動すると ElephantDetailPage
が表示されます。 詳細については、「コンテキストに応じたナビゲーション」を参照してください。
Note
Routing.RegisterRoute
メソッドを使ってルートが登録されたページは、必要に応じて、Routing.UnRegisterRoute
メソッドを使って登録解除できます。
ナビゲーションを実行する
ナビゲーションを実行するには、最初に Shell サブクラスへの参照を取得する必要があります。 この参照は、 Shell.Current
プロパティを使用して取得できます。 その後、Shell オブジェクト上の GoToAsync メソッドを呼び出すことで、ナビゲーションを実行できます。 このメソッドでは ShellNavigationState
へ移動して、ナビゲーションのアニメーションが終わったら完了する Task
を返します。 ShellNavigationState
オブジェクトは、string
または Uri
から、GoToAsync メソッドによって構成され、string
または Uri
引数に設定された Location
プロパティを備えています。
重要
シェルの視覚階層のルートに移動する場合、ナビゲーション スタックは作成されません。 しかし、シェルの視覚階層にはないページに移動する場合は、ナビゲーション スタックが作成されます。
Shell オブジェクトの現在のナビゲーションの状態は、Shell.Current.CurrentState
プロパティ経由で取得できます。Location
プロパティに、表示されるルートの URI が含まれます。
絶対ルート
有効な絶対 URI を GoToAsync メソッドへの引数として指定することで、ナビゲーションを実行できます。
await Shell.Current.GoToAsync("//animals/monkeys");
この例では、ShellContent オブジェクトに対して定義されたルートを使って、monkeys
ルートのページへ移動します。 monkeys
ルートを表している ShellContent オブジェクトは FlyoutItem オブジェクトの子であり、そのルートは animals
になっています。
相対ルート
有効な相対 URI を GoToAsync メソッドへの引数として指定することで、ナビゲーションを実行することもできます。 ルーティング システムでは、ShellContent オブジェクトの URI との一致を試みます。 そのため、アプリ内のすべてのルートが固有の場合は、相対 URI として一意のルート名を指定するだけで、ナビゲーションを実行できます。
次の相対ルート形式がサポートされます。
書式 | 説明 |
---|---|
route | 現在の位置から上位方向に、指定されたルートを求めてルート階層が検索されます。 一致するページがナビゲーション スタックにプッシュされます。 |
/route | 現在の位置から下位方向に、指定されたルートを求めてルート階層が検索されます。 一致するページがナビゲーション スタックにプッシュされます。 |
//route | 現在の位置から上位方向に、指定されたルートを求めてルート階層が検索されます。 一致するページによって、ナビゲーション スタックが置き換えられます。 |
///route | 現在の位置から下位方向に、指定されたルートを求めてルート階層が検索されます。 一致するページによって、ナビゲーション スタックが置き換えられます。 |
次の例では、monkeydetails
ルートのページに移動します。
await Shell.Current.GoToAsync("monkeydetails");
この例では、一致するページが見つかるまで、monkeyDetails
ルートが階層の上位方向に検索されます。 該当するページが見つかったら、ナビゲーション スタックにプッシュされます。
コンテキストに応じたナビゲーション
相対ルートでは、コンテキストに応じたナビゲーションが可能です。 たとえば、次のようなルート階層を検討します。
monkeys
details
bears
details
monkeys
ルートに登録したページが表示されているときに、details
ルートに移動すると、monkeys/details
ルートに登録したページが表示されます。 同様に、bears
ルートに登録したページが表示されているときに、details
ルートに移動すると、bears/details
ルートに登録したページが表示されます。 この例でのルートの登録方法については、「ページのルートを登録する」をご覧ください。
後方ナビゲーション
".." を GoToAsync メソッドへの引数として指定することで、後方ナビゲーションを実行できます。
await Shell.Current.GoToAsync("..");
".." を使用した後方ナビゲーションは、ルートと組み合わせることもできます。
await Shell.Current.GoToAsync("../route");
この例では、後方ナビゲーションが実行されてから、指定したルートへ移動します。
重要
後方ナビゲーション後に指定したルートに移動するには、指定したルートに移動するように、後方ナビゲーションによってルート階層の現在の場所に移動する必要があります。
同様に、後方に複数回移動してから、指定したルートに移動することもできます。
await Shell.Current.GoToAsync("../../route");
この例では、後方ナビゲーションが 2 回実行されてから、指定したルートに移動します。
さらに、後方に移動する場合は、クエリのプロパティを介してデータを渡すこともできます。
await Shell.Current.GoToAsync($"..?parameterToPassBack={parameterValueToPassBack}");
この例では、後方ナビゲーションが実行されてから、クエリ パラメーターの値が前のページのクエリ パラメーターに渡されます。
Note
クエリ パラメーターは、任意の後方ナビゲーション要求に追加することができます。
移動時にデータを渡す方法の詳細については、「データを渡す」を参照してください。
無効なルート
次のルート形式は無効です。
形式 | 説明 |
---|---|
//page または ///page | 現在、グローバル ルートをナビゲーション スタック上の唯一のページにはできません。 そのため、グローバル ルートへの絶対ルーティングはサポートされていません。 |
これらのルート形式を使用すると、Exception
がスローされます。
警告
存在しないルートへのナビゲーションを試行すると、ArgumentException
例外がスローされます。
ナビゲーションをデバッグする
一部の Shell クラスは、クラスまたはフィールドがデバッガーによって表示される方法を指定する DebuggerDisplayAttribute
によって修飾されています。 これにより、ナビゲーション要求に関連付けられたデータを表示して、ナビゲーション要求をデバッグできます。 たとえば、次のスクリーンショットには、Shell.Current
オブジェクトの CurrentItem
および CurrentState
プロパティが表示されています。
この例では、FlyoutItem 型の CurrentItem
プロパティによって、FlyoutItem オブジェクトのタイトルとルートを表示します。 同様に、ShellNavigationState
型の CurrentState
プロパティによって、シェル アプリ内で表示されるルートの URI が表示されます。
ナビゲーション スタック
Tab クラスには、Tab 内の現在のナビゲーション スタックを表す、IReadOnlyList<Page>
型の Stack
プロパティが定義されています。このクラスでは、次のオーバーライド可能なナビゲーション メソッドも提供されます。
GetNavigationStack
: 現在のナビゲーション スタックを示すIReadOnlyList<Page>
を返します。OnInsertPageBefore
:INavigation.InsertPageBefore
が呼び出されたときに、呼び出されます。OnPopAsync
:Task<Page>
を返し、INavigation.PopAsync
が呼び出されたときに、呼び出されます。OnPopToRootAsync
:Task
を返し、INavigation.OnPopToRootAsync
が呼び出されたときに、呼び出されます。OnPushAsync
:Task
を返し、INavigation.PushAsync
が呼び出されたときに、呼び出されます。OnRemovePage
:INavigation.RemovePage
が呼び出されたときに、呼び出されます。
OnRemovePage
メソッドをオーバーライドする方法を次の例に示します。
public class MyTab : Tab
{
protected override void OnRemovePage(Page page)
{
base.OnRemovePage(page);
// Custom logic
}
}
この例では、MyTab
オブジェクトは、Tab オブジェクト内ではなく、シェルのビジュアル階層内で使用されます。
ナビゲーション イベント
Shell クラスでは、プログラムによるナビゲーションまたはユーザー操作のどちらかに起因して、ナビゲーションが実行されるときに発生する Navigating
イベントを定義しています。 Navigating
イベントに伴う ShellNavigatingEventArgs
オブジェクトでは、次のプロパティを提供しています。
プロパティ | タイプ | 説明 |
---|---|---|
Current |
ShellNavigationState |
現在のページの URI。 |
Source |
ShellNavigationSource |
発生したナビゲーションの種類。 |
Target |
ShellNavigationState |
ナビゲーションの発信先を表す URI。 |
CanCancel |
bool |
ナビゲーションをキャンセルできるかどうかを示す値。 |
Cancelled |
bool |
ナビゲーションがキャンセルされたかどうかを示す値。 |
さらに、ShellNavigatingEventArgs
クラスには、ナビゲーションを取り消すために使用できる Cancel
メソッドと、ナビゲーションを完了するために使用できる ShellNavigatingDeferral
トークンを返す GetDeferral
メソッドが用意されています。 ナビゲーションの遅延の詳細については、「ナビゲーションの遅延」を参照してください。
また、Shell クラスでは、ナビゲーションが完了したときに発生する Navigated
イベントも定義しています。 Navigated
イベントに伴う ShellNavigatedEventArgs
オブジェクトでは、次のプロパティを提供しています。
プロパティ | タイプ | 説明 |
---|---|---|
Current |
ShellNavigationState |
現在のページの URI。 |
Previous |
ShellNavigationState |
前のページの URI。 |
Source |
ShellNavigationSource |
発生したナビゲーションの種類。 |
重要
Navigating
イベントが発生すると、OnNavigating
メソッドが呼び出されます。 同様に、Navigated
イベントが発生すると、OnNavigated
メソッドが呼び出されます。 どちらのメソッドも、Shell サブクラスでオーバーライドして、ナビゲーション要求をインターセプトすることができます。
ShellNavigatedEventArgs
および ShellNavigatingEventArgs
クラスの両方に、ShellNavigationSource
型の Source
プロパティがあります。 この列挙体では、次の値を提供しています。
Unknown
Push
Pop
PopToRoot
Insert
Remove
ShellItemChanged
ShellSectionChanged
ShellContentChanged
そのため、ナビゲーションを OnNavigating
オーバーライドでインターセプトでき、アクションをナビゲーション ソースに基づいて実行できます。 たとえば、次のコードでは、ページ上のデータが未保存の場合に、前に戻るナビゲーションをキャンセルする方法を示しています。
protected override void OnNavigating(ShellNavigatingEventArgs args)
{
base.OnNavigating(args);
// Cancel any back navigation.
if (args.Source == ShellNavigationSource.Pop)
{
args.Cancel();
}
}
ナビゲーションの遅延
シェルのナビゲーションは、インターセプトされ、ユーザーの選択に基づいて完了またはキャンセルされます。 これを実現するには、Shell サブクラス内の OnNavigating
メソッドをオーバーライドし、ShellNavigatingEventArgs
オブジェクト上の GetDeferral
メソッドを呼び出します。 このメソッドからは、Complete
メソッドを含む ShellNavigatingDeferral
トークンが返され、ナビゲーション要求を完了するために使用できます。
public MyShell : Shell
{
// ...
protected override async void OnNavigating(ShellNavigatingEventArgs args)
{
base.OnNavigating(args);
ShellNavigatingDeferral token = args.GetDeferral();
var result = await DisplayActionSheet("Navigate?", "Cancel", "Yes", "No");
if (result != "Yes")
{
args.Cancel();
}
token.Complete();
}
}
この例では、ナビゲーション要求を完了またはキャンセルするユーザーを招待するアクション シートが表示されます。 ShellNavigatingEventArgs
オブジェクト上の Cancel
メソッドを呼び出すと、ナビゲーションは取り消されます。 ShellNavigatingEventArgs
オブジェクト上の GetDeferral
メソッドによって取得された ShellNavigatingDeferral
トークン上で Complete
メソッドを呼び出すことで、ナビゲーションは完了します。
警告
保留中のナビゲーション遅延があるときにユーザーが移動しようとすると、GoToAsync メソッドから InvalidOperationException
がスローされます。
データを渡す
URI ベースのプログラム ナビゲーションを実行する場合は、文字列ベースのクエリ パラメーターとしてプリミティブ データを渡すことができます。 これは、ルートの後に ?
に続けて、クエリ パラメーター ID、=
、値を追加することによって実現されます。
async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
string elephantName = (e.CurrentSelection.FirstOrDefault() as Animal).Name;
await Shell.Current.GoToAsync($"elephantdetails?name={elephantName}");
}
この例では、CollectionView 内の現在選択されている象を取得し、elephantName
をクエリ パラメーターとして渡して elephantdetails
ルートに移動します。
複数使用のオブジェクト ベースのナビゲーション データを渡す
複数使用のオブジェクト ベースのナビゲーション データは、IDictionary<string, object>
引数を指定する GoToAsync オーバーロードで渡すことができます。
async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
Animal animal = e.CurrentSelection.FirstOrDefault() as Animal;
var navigationParameter = new Dictionary<string, object>
{
{ "Bear", animal }
};
await Shell.Current.GoToAsync($"beardetails", navigationParameter);
}
この例では、CollectionView 内の現在選択されている熊を Animal
として取得します。 Animal
オブジェクトは、キー Bear
を持つ Dictionary
に追加されます。 次に、beardetails
ルートへのナビゲーションが実行され、Dictionary
がナビゲーション パラメーターとして渡されます。
IDictionary<string, object>
引数として渡されたデータは、ページの有効期間中メモリに保持され、ページがナビゲーション スタックから削除されるまで解放されません。 これは、次のシナリオに示すように、問題となる可能性があります。
Page1
は GoToAsync メソッドを使用してMyData
というオブジェクト渡し、Page2
に移動します。 その後、Page2
はMyData
をクエリ パラメーターとして受け取ります。Page2
は、データを渡さずに、GoToAsync メソッドを使用してPage3
に移動します。Page3
は GoToAsync メソッドを使用して後方に移動します。 その後、Page2
はMyData
をクエリ パラメーターとして再び受け取ります。
これは多くのシナリオで望ましいことですが、望ましくない場合は、ページが最初に受け取った後に Clear
メソッドを使用して IDictionary<string, object>
引数をクリアする必要があります。
使い捨てのオブジェクト ベースのナビゲーション データを渡す
使い捨てのオブジェクト ベースのナビゲーション データは、ShellNavigationQueryParameters 引数を指定する GoToAsync オーバーロードで渡すことができます。 ShellNavigationQueryParameters オブジェクトは、ナビゲーションが発生した後にクリアされる使い捨てのナビゲーション データを対象としています。 次の例は、使い捨てのデータを渡しながら移動する方法を示しています。
async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
Animal animal = e.CurrentSelection.FirstOrDefault() as Animal;
var navigationParameter = new ShellNavigationQueryParameters
{
{ "Bear", animal }
};
await Shell.Current.GoToAsync($"beardetails", navigationParameter);
}
この例では、CollectionView 内で現在選択されているクマを、ShellNavigationQueryParameters オブジェクトに追加された Animal
として取得します。 次に、ShellNavigationQueryParameters オブジェクトがナビゲーション パラメーターとして渡され、beardetails
ルートへのナビゲーションが実行されます。 ナビゲーションが発生すると、ShellNavigationQueryParameters オブジェクト内のデータがクリアされます。
ナビゲーション データを受信する
ナビゲーション データを受信するには、次の 2 つの方法があります。
- 移動先ページを表すクラスまたはページの
BindingContext
に対応するクラスを、各クエリ パラメーターの QueryPropertyAttribute で修飾できます。 詳細については、「クエリ プロパティ属性を使用してナビゲーション データを処理する」を参照してください。 - 移動先のページを表すクラス、またはページの
BindingContext
のクラスを使用すると、IQueryAttributable インターフェイスを実装できます。 詳細については、「単一のメソッドを使用してナビゲーションデータを処理する」を参照してください。
クエリ プロパティ属性を使用してナビゲーション データを処理する
ナビゲーション データは、受信するクラスの文字列ベースの各クエリ パラメーター、オブジェクト ベースのナビゲーション パラメーター、または ShellNavigationQueryParameters オブジェクトを QueryPropertyAttribute で修飾すると受信できます。
[QueryProperty(nameof(Bear), "Bear")]
public partial class BearDetailPage : ContentPage
{
Animal bear;
public Animal Bear
{
get => bear;
set
{
bear = value;
OnPropertyChanged();
}
}
public BearDetailPage()
{
InitializeComponent();
BindingContext = this;
}
}
この例では、QueryPropertyAttribute の最初の引数には、データを受信するプロパティの名前を指定し、2 番目の引数にはパラメータ― ID を指定します。そのため、上の例の QueryPropertyAttribute において、GoToAsync メソッドの呼び出しで Bear
ナビゲーション パラメーターで渡されたデータを Bear
プロパティが受け取るように指定されています。
重要
QueryPropertyAttribute を介して受信した文字列ベースのクエリ パラメーター値は、自動的に URL デコードされます。
警告
QueryPropertyAttributeを使用してナビゲーション データを受信することは安全なトリミングではなく、フル トリミングや NativeAOT では使用しないでください。 代わりに、クエリ パラメーターを受け入れる必要がある型に IQueryAttributable インターフェイスを実装する必要があります。 詳細については、「 1 つのメソッドを使用したデータの処理.NET MAUI アプリの作成Native AOT デプロイを参照してください。
単一のメソッドを使用してナビゲーション データを処理する
ナビゲーション データは、受信クラスに IQueryAttributable インターフェイスを実装すると受信することができます。 IQueryAttributable インターフェイスを使用して、実装するクラスで ApplyQueryAttributes
メソッドを実装する必要があることを指定します。 このメソッドには、ナビゲーション中に渡されたデータを含む IDictionary<string, object>
型の query
引数があります。 ディクショナリ内の各キーはクエリ パラメーター ID であり、その値はデータを表すオブジェクトに対応します。 この方法を使用する利点は、1 つのメソッドを使用してナビゲーション データを処理できることです。これは、全体として処理が必要なナビゲーション データの複数の項目がある場合に便利です。
次の例は、IQueryAttributable インターフェイスを実装するビュー モデル クラスを示しています。
public class MonkeyDetailViewModel : IQueryAttributable, INotifyPropertyChanged
{
public Animal Monkey { get; private set; }
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
Monkey = query["Monkey"] as Animal;
OnPropertyChanged("Monkey");
}
...
}
この例では、ApplyQueryAttributes
メソッドは query
ディクショナリ内の Monkey
キーに対応するオブジェクトを取得します。このオブジェクトは、GoToAsync メソッドの呼び出しに引数として渡されました。
重要
IQueryAttributable インターフェイスを介して受信した文字列ベースのクエリ パラメータ値は自動的に URL デコードされません。
複数のデータ項目を渡して処理する
複数の文字列ベースのクエリ パラメーターを渡すには、これらのパラメーターを &
でつなげます。 たとえば、次のコードでは 2 つのデータ項目が渡されます。
async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
string elephantName = (e.CurrentSelection.FirstOrDefault() as Animal).Name;
string elephantLocation = (e.CurrentSelection.FirstOrDefault() as Animal).Location;
await Shell.Current.GoToAsync($"elephantdetails?name={elephantName}&location={elephantLocation}");
}
このコード サンプルでは、CollectionView 内の現在選択されているゾウを取得し、elephantName
および elephantLocation
をクエリ パラメーターとして渡して elephantdetails
ルートに移動します。
データの複数の項目を受信するために、移動先ページを表すクラスや、ページの BindingContext
のクラスで、各文字列ベースのクエリ パラメーターを QueryPropertyAttribute で修飾できます。
[QueryProperty(nameof(Name), "name")]
[QueryProperty(nameof(Location), "location")]
public partial class ElephantDetailPage : ContentPage
{
public string Name
{
set
{
// Custom logic
}
}
public string Location
{
set
{
// Custom logic
}
}
...
}
この例では、クラスは各クエリ パラメーターの QueryPropertyAttribute によって修飾されています。 最初の QueryPropertyAttribute では、name
クエリ パラメーターに渡されたデータを Name
プロパティが受信するように指定しており、2 番目の QueryPropertyAttribute では、location
クエリ パラメーターに渡されたデータを Location
プロパティが受信するように指定しています。 どちらの場合も、クエリ パラメーターの値は、GoToAsync メソッド呼び出しの URI で指定されます。
警告
QueryPropertyAttributeを使用してナビゲーション データを受信することは安全なトリミングではなく、フル トリミングや NativeAOT では使用しないでください。 代わりに、クエリ パラメーターを受け入れる必要がある型に IQueryAttributable インターフェイスを実装する必要があります。 詳細については、「 .NET MAUI アプリの作成 および Native AOT のデプロイを参照してください。
または、移動先のページを表すクラスまたはページの BindingContext
のクラスに IQueryAttributable インターフェイスを実装することで、1 つのメソッドでナビゲーション データを処理することもできます。
public class ElephantDetailViewModel : IQueryAttributable, INotifyPropertyChanged
{
public Animal Elephant { get; private set; }
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
string name = HttpUtility.UrlDecode(query["name"].ToString());
string location = HttpUtility.UrlDecode(query["location"].ToString());
...
}
...
}
この例では、ApplyQueryAttributes
メソッドを使用して、GoToAsync メソッド呼び出しの URI から name
および location
のクエリ パラメーターの値を取得します。
Note
ルート ベースのナビゲーションを実行するときに、文字列ベースのクエリ パラメーターとオブジェクト ベースのナビゲーション パラメーターを同時に渡すことができます。
[戻る] ボタンの動作
戻るボタンの外観と動作は、BackButtonBehavior 添付プロパティを BackButtonBehavior オブジェクトに設定することによって再定義できます。 BackButtonBehavior クラスには、次のプロパティが定義されています。
Command
: ICommand 型、戻るボタンが押されたときに実行されます。CommandParameter
:object
型、Command
に渡されるパラメーター。IconOverride
: ImageSource 型、戻るボタンに使用されるアイコンです。boolean
型のIsEnabled
は、戻るボタンが有効かどうかを示します。 既定値はtrue
です。boolean
型のIsVisible
は、戻るボタンが表示されるかどうかを示します。 既定値はtrue
です。TextOverride
:string
型、戻るボタンに使用されるテキスト。
これらのプロパティはすべて、BindableProperty オブジェクトを基盤としています。つまり、プロパティはデータ バインディングの対象にすることができます。 各 BindableProperty には OneTime
バインド モードがあります。つまり、データはソースからターゲットに移行されますが、BindingContext
が変更された場合にのみ行われます。
これらのプロパティはすべて、BindableProperty オブジェクトを基盤としています。つまり、プロパティはデータ バインディングの対象にすることができます。 Command
、CommandParameter
、IconOveride
、TextOveride
BindableProperty オブジェクトにはOneTime
バインド モードがあります。つまり、データはソースからターゲットに移行されますが、BindingContext
が変更された場合にのみ行われます。 IsEnabled
オブジェクトと IsVisible
BindableProperty オブジェクトには OneWay
バインド モードがあります。つまり、データはソースからターゲットに移行されます。
次のコードは、戻るボタンの外観と動作を再定義する例を示しています。
<ContentPage ...>
<Shell.BackButtonBehavior>
<BackButtonBehavior Command="{Binding BackCommand}"
IconOverride="back.png" />
</Shell.BackButtonBehavior>
...
</ContentPage>
Command
プロパティは、戻るボタンが押されたときに実行されるように ICommand に設定され、IconOverride
プロパティは、戻るボタンに使用されるアイコンに設定されます。
.NET MAUI