Prism 6 for UWP(2)~画面遷移のパラメータ

Posted by 技術ブログ by Strawhat.net on Tuesday, October 20, 2015

Prism 6 for UWPではNavigationService.Navigate("Main", null);のようにNavigateメソッドで画面遷移します。

この画面遷移で、次の画面にパラメータを渡す方法を紹介します。

サンプルコードは以下のプロジェクトから、PrismForUWPSample/01-Basic/01-02-PrismBasicAppWithParamを見てください。

PrismForUWPSample/01-Basic/01-01-PrismBasicApp

Navigateのパラメータとして渡す

NavigationService.Navigateメソッドの第2引数object parameterは、遷移先画面のOnNavigatedToメソッドの第1引数NavigatedToEventArgs eでe.Parameterとして渡されます。

public override void OnNavigatedTo(NavigatedToEventArgs e, Dictionary<string, object> viewModelState)
{
    base.OnNavigatedTo(e, viewModelState);
    this.Text = e.Parameter as string;
}

受け取り先ではobjectから目的の型にキャストして、パラメータを受け取ります。

補足

Navigateメソッドの第2引数について、@okazukiさんから指摘を頂きました。

第2引数はobject型ですが、任意の型を渡せる訳ではなくて、「文字列、文字、数字、GUID 型など、ナビゲーション パラメーターの基本型」しか渡せません。

それ以外の型を渡すと、中断時に「GetNavigationState doesn’t support serialization of a parameter type which was passed to Frame.Navigate.」との例外が発生します。

ApplicationData.Current.LocalSettings.Valuesに保存して渡す

ApplicationData.Current.LocalSettingsプロパティ(ApplicationDataContainerクラス)が持つ Valuesプロパティ(IPropertySetインターフェース)に値を格納して受け渡す方法です。

ApplicationData Class

ValuesプロパティはMapとしてアクセスします。

public override void OnNavigatedTo(NavigatedToEventArgs e, Dictionary<string, object> viewModelState)
{
    base.OnNavigatedTo(e, viewModelState);
    if (e.NavigationMode == Windows.UI.Xaml.Navigation.NavigationMode.Back)
    {
        if (ApplicationData.Current.LocalSettings.Values.ContainsKey("Age"))
        {
            this.Age = (int)ApplicationData.Current.LocalSettings.Values["Age"];
            ApplicationData.Current.LocalSettings.Values.Remove("Age");
        }
    }
}

ただし、キー名は最大255文字、設定項目の値は8KBまでの制限事項があります。 また、格納できる値はWindows Runtimeでサポートされた単純な型に限られます。

ApplicationData.Current.LocalSettings.Containersに保存して渡す

階層構造を持った値を渡す場合は、IReadOnlyDictionary<String, ApplicationDataContainer>型のLocalSettings.Containersプロパティを使います。

遷移元の画面では、LocalSettings.CreateContainerメソッドでApplicationDataContainerコンテナを作成します。 第1引数はコンテナの名称、第2引数は基本的にApplicationDataCreateDisposition.Alwaysを指定します。

作成したコンテナcontainerには、container[“キー文字列”].Valuesに値を格納できます。 また、container.CreateContainerメソッドでコンテナを作成してサブ構造を作ることができます。

var container1 = ApplicationData.Current.LocalSettings.CreateContainer("ContainerA", ApplicationDataCreateDisposition.Always);
container1.Values["key11"] = "string11";
container1.Values["key12"] = "string12";

var subcontainer1 = container1.CreateContainer("ContainerAA", ApplicationDataCreateDisposition.Always);
subcontainer1.Values["key111"] = "string111";

遷移先の画面では‘LocalSettings.Containers[“ContainerA”]‘でコンテナを取得して、 Valuesプロパティで値を、Containersプロパティでサブコンテナを取得できます。

var container1 = ApplicationData.Current.LocalSettings.Containers["ContainerA"];
var value11 = container1.Values["key11"];

var subcontainer1 = container1.Containers["ContainerAA"];
var value111 = subcontainer1.Values["key111"];

(実際には、キーが存在するかContainsKeyで確認したほうがよいです。)

さらに複雑なデータ、大容量のデータの場合

この場合、ApplicationData.Current.LocalFolderでアプリのデータを格納するフォルダ (Windows.Storage.StorageFolderクラス)を取得して、JSON・XML・バイナリなど 都合のよい形式でファイルにデータを格納することになります。

そのファイルの情報を上記のいずれかの方法で渡すことになります。