Xamarin Forms Prism 頁面巡覽與參數傳遞
本篇介紹的是如何使用Prism所提供的NavigationService進行頁面之間的巡覽與參數傳遞。
使用URL方式巡覽
本篇介紹的是如何使用Prism所提供的NavigationService進行頁面之間的巡。
所有的頁面要使用巡覽服務前,都必須確認他有被註冊過。
頁面註冊
假設有MainPage與View1Page頁,都需要在App.cs中RegisterTypes()註冊:
containerRegistry.RegisterForNavigation<NavigationPage>();
containerRegistry.RegisterForNavigation<MainPage, MainPageViewModel>();
containerRegistry.RegisterForNavigation<View1Page, View1PageViewModel>();
註冊頁面時可使用明確指定對應ViewModel的方式,
或者使用預設內建的反射自動對應來註冊,
以註冊MainPage程式來說,會將MainPage對應到MainViewModel,
並以字串「MainPage」最為巡覽時所用的名稱。
如果要更改導航時所用的字串名稱,可以在註冊時傳入想要使用的名稱:
containerRegistry.RegisterForNavigation<MainPage, MainPageViewModel>("FirstView");
在App.cs的OnInitialized方法中,可使用Prism已實作出的NavigationService進行首頁的指定。
await NavigationService.NavigateAsync("FirstView");
頁面如果需要多頁巡覽時,在最開始的層級要先放置一個NavigationPage
await NavigationService.NavigateAsync("NavigationPage/FirstView");
使用NavigationService
在ViewModel中如果需要使用NavigationService,
則需要在建構子中將型別INavigationService做為傳入的參數,
並且參數名稱固定一定要使用navigationService,否則會拿不到東西。
建議直接繼承範本提供的ViewModelBase。
相對位置巡覽
假設目前的導航的所在路徑是NavigationPage/FirstView,
對Navigation目前的堆疊就只有FirstView,
如果想要巡覽到View1Page,讓堆疊變成 FirstView/View1Page,
則可用NavigationService的NavigateAsync巡覽至View1Page。
this.NavigationService.NavigateAsync("View1Page");
絕對位置巡覽
某些清況下,可能會需要將目前的整個巡覽替換掉(像是登入後這類的需求等..),
這時候可使用絕對位置的巡覽方式。
就相當於指定了Application.Current.MainPage。
使用絕對位置只要在最開始處使用「/」符號。
this.NavigationService.NavigateAsync("/View1Page");
回上一頁
要讓巡覽回到上一頁非常簡單,只要使用NavigationService的GoBackAsync方法
this.NavigationService.GoBackAsync();
使用Model模式
通常會Model一個新的畫面出來,
是為了分開兩個不同功能的巡覽流程,
意即新Model出來的視窗會有自己的巡覽堆疊。
同樣的還是使用了NavigateAsync方法,但多傳了useModalNavigation=true參數。
this.NavigationService.NavigateAsync("View1Page", useModalNavigation: true);
而當新Model的出視窗流程要結束時,同樣也是使用GoBackAsync方法,
並使用useModalNavigation=true參數,如果不傳參數有可能無法正常運作。
this.NavigationService.GoBackAsync(useModalNavigation: true);
參數傳遞
使用QurryString
巡覽的過程中如果有需要將參數傳遞到下一個畫面會傳回上個畫面時,
最快的方式是使用QueryString的方式將簡單的參數傳遞到下一個畫面。
this.NavigationService.NavigateAsync("View1Page?id=123");
使用NavigationParameters
當需要傳遞的參數較多或者需要將物件傳遞到下一個頁面時,
可使用NavigationParameters類別來封裝多個參數。
NavigationParameters datas = new NavigationParameters();
datas.Add("data1", new MyDataItem() { Value="100" });
datas.Add("data2", "456");
datas.Add("id", "123");
this.NavigationService.NavigateAsync("View1Page", datas);
當然也可以將兩種混合使用:
NavigationParameters datas = new NavigationParameters();
datas.Add("data1", new MyDataItem() { Value="100" });
datas.Add("data2", "456");
this.NavigationService.NavigateAsync("View1Page?id=123", datas);
同樣的,使用NavigationParameters也可將參數傳回上一頁:
this.OnBack = new DelegateCommand(() =>
{
NavigationParameters datas = new NavigationParameters();
datas.Add("dataBack", "789");
this.NavigationService.GoBackAsync(datas);
});
接收參數
當參數傳遞到下一頁時,複寫繼承至ViewModelBase中的Initialize方法,
可在方法中取得傳入的參數。
要取得參數值,則使用INavigationParameters的方法GetValue<T>來取得。
var id= parameters.GetValue<string>("id");
var data1 = parameters.GetValue<MyDataItem>("data1");
var data2 = parameters.GetValue<string>("data2");
如果是要接收由下一頁傳回的參數,則需在接收參數頁的ViewModel中複寫ViewModelBase的OnNavigatedTo方法取得參數
public override void OnNavigatedTo(INavigationParameters parameters)
{
base.OnNavigatedTo(parameters);
var backValue = parameters.GetValue<string>("dataBack");
}
判斷巡覽模式
由於OnNavigatedTo在進入該頁面時都會被叫用(某些情況下不會觸發,如實體按鈕退回一頁等),
如果該頁同時要接收前一頁傳來跟下一頁回傳的參數,
就會需要判斷到底是前頁還是後頁,
INavigationParameters提供了GetNavigationMode方法,
可取得NavigationMode列舉值(Xamarin Forms僅支援Back與New)
New表示由上一頁傳遞過來的,
Back則是下一頁返回傳遞過來的。
範例連結
https://github.com/stevenchang0529/Xamarin.Lab.PrismNavigation