.NET 多平臺應用程式 UI (.NET MAUI) NavigationPage 提供階層式瀏覽體驗,讓您能夠視需要瀏覽頁面、向前和向後流覽。 NavigationPage 提供導覽做為對象的最後進階、先出 (LIFO) 堆疊 Page 。
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 也會定義三個事件:
-
Pushed當頁面推送至瀏覽堆疊時,就會引發 。 -
Popped從導覽堆疊中彈出頁面時引發。 -
PoppedToRoot從瀏覽堆疊彈出最後一個非根頁面時,會引發 。
這三個事件都會接收 NavigationEventArgs 定義只讀 Page 屬性的物件,它會擷取從流覽堆疊快顯的頁面,或堆疊上新可見的頁面。
警告
NavigationPage 與 .NET MAUI Shell 應用程式不相容,如果您嘗試在Shell應用程式中使用 NavigationPage ,將會擲回例外狀況。 如需殼層應用程式的詳細資訊,請參閱 Shell。
執行無模式導覽
.NET MAUI 支援無模式頁面流覽。 無模式頁面會停留在畫面上,直到您流覽至另一個頁面為止。
NavigationPage通常用來巡覽物件堆疊ContentPage。 當某個頁面巡覽至另一個頁面時,新頁面會在堆疊上推送,並成為使用中的頁面:
當第二頁返回第一頁時,會從堆疊中彈出頁面,然後新的最上層頁面會變成使用中:
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()));
}
}
注意
的 RootPageNavigationPage 屬性提供流覽堆疊中第一頁的存取權。
將頁面推送至瀏覽堆疊
在目前頁面的 屬性上PushAsync呼叫 Navigation 方法,即可巡覽至頁面:
await Navigation.PushAsync(new DetailsPage());
在此範例中 DetailsPage ,物件會推送至流覽堆疊,其中會變成使用中的頁面。
注意
方法 PushAsync 具有覆寫,其中包含自 bool 變數,指定是否要在瀏覽期間顯示頁面轉換。
PushAsync缺少 bool 自變數的方法預設會啟用頁面轉換。
流覽堆疊中的快顯頁面
不論這是裝置上的實體按鈕還是螢幕按鈕,都可以從流覽堆疊中彈出使用中的頁面。
若要以程式設計方式返回上一頁, PopAsync 應該在目前頁面的 屬性上 Navigation 呼叫 方法:
await Navigation.PopAsync();
在此範例中,目前頁面會從流覽堆疊中移除,而新的最上層頁面會變成使用中頁面。
注意
方法 PopAsync 具有覆寫,其中包含自 bool 變數,指定是否要在瀏覽期間顯示頁面轉換。
PopAsync缺少 bool 自變數的方法預設會啟用頁面轉換。
此外, Navigation 每個頁面的 屬性也會公開 PopToRootAsync 方法,該方法會從流覽堆疊中快顯所有根頁面,因此讓應用程式的根頁面成為使用中頁面。
操作流覽堆疊
的 NavigationPage 屬性會 NavigationStack 公開屬性,可從中取得導覽堆疊中的頁面。 雖然 .NET MAUI 會維護流覽堆疊的存取權, Navigation 但 屬性會藉由插入頁面或移除頁面來提供 InsertPageBefore 和 RemovePage 方法來操作堆棧。
InsertPageBefore 方法會將指定的頁面插入導覽堆疊中現有指定頁面之前,如下圖所示:
RemovePage 方法會從導覽堆疊中移除指定的頁面,如下圖所示:
這些方法一起會啟用自定義導覽體驗,例如,在成功登入之後,以新的頁面取代登入頁面。
執行強制響應流覽
.NET MAUI 支援強制回應頁面流覽。 強制回應頁面鼓勵使用者完成各自獨立且無法離開的工作,直到完成或取消工作為止。
強制回應頁面可以是 .NET MAUI 所支援的任何頁面類型。 若要以模式顯示頁面,應用程式應該將其推送至強制回應堆疊,其中會變成使用中的頁面:
若要返回上一頁,應用程式應該從強制回應堆疊快顯目前頁面,而新的最上層頁面會變成使用中頁面:
Navigation 屬性會在任何 Page 衍生類型上公開強制回應導覽方法。 這些方法可讓您將頁面推送至強制回應堆疊,以及強制回應堆疊中的快顯頁面。 屬性 Navigation 也會公開 ModalStack 屬性,可從中取得強制回應堆疊中的頁面。 不過,沒有執行強制回應堆疊操作,或快顯至強制回應導覽中根目錄的概念。 這是因為基礎平台上普遍不支援這些作業。
注意
NavigationPage執行強制回應頁面流覽不需要物件。
將頁面推送至強制回應堆疊
在目前頁面的 屬性上PushModalAsync呼叫 Navigation 方法,即可強制巡覽頁面:
await Navigation.PushModalAsync(new DetailsPage());
在此範例中 DetailsPage ,物件會推送至強制回應堆疊,而該堆疊會變成使用中的頁面。
注意
方法 PushModalAsync 具有覆寫,其中包含自 bool 變數,指定是否要在瀏覽期間顯示頁面轉換。
PushModalAsync缺少 bool 自變數的方法預設會啟用頁面轉換。
強制回應堆疊中的快顯頁面
不論這是裝置上的實體按鈕或螢幕上的按鈕,都可以從強制回應堆棧彈出使用中頁面。
若要以程式設計方式返回原始頁面, PopModalAsync 應該在目前頁面的 屬性上 Navigation 呼叫 方法:
await Navigation.PopModalAsync();
在此範例中,目前的頁面會從強制回應堆疊中移除,而新的最上層頁面會變成使用中頁面。
注意
方法 PopModalAsync 具有覆寫,其中包含自 bool 變數,指定是否要在瀏覽期間顯示頁面轉換。
PopModalAsync缺少 bool 自變數的方法預設會啟用頁面轉換。
停用返回按鈕
在 Android 上,您可以按裝置上的標準 [上一頁 ] 按鈕,一律返回上一頁。 如果強制回應頁面需要在離開頁面之前完成獨立工作,應用程式必須停用 [ 上一步 ] 按鈕。 這可以透過覆寫強制回應頁面上的 Page.OnBackButtonPressed 方法來完成。
頁面導覽事件
這個Page類別定義了NavigatedTo、NavigatingFrom 和NavigatedFrom,這些是在頁面瀏覽過程中觸發的導航事件。
NavigatingFrom當當前頁面即將被導離時,事件會被觸發。
NavigatedFrom事件是在當前頁面被導離後才被提出的。
NavigatedTo事件在瀏覽當前頁面後會被觸發。
注意
在 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 在這個方法中,你可以從資料庫或網路服務中填入一組項目。
在瀏覽期間傳遞數據
有時必須在巡覽期間將某頁資料傳遞到另一頁。 完成這項作業的兩種標準技術是透過頁面建構函式傳遞數據,以及將新頁面的 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 傳遞數據
在瀏覽期間將資料傳遞至另一個頁面的替代方法是將新頁面 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 屬性更容易取得您想要的導覽列設計。