Windows Store Appsのページ移動で渡すパラメータによるSuspensionManagerエラーの解決方法

最近Windows Store Appsを少々勉強中ですが、当たり前にできるだろうよ思われることができなかったり、こんなことまでできるの?ってことがあったりいろいろ苦労しています。今回はWindows Store Appsの様々なサンプルアプリに入っているSuspensionManagerクラスのSaveAsync()時に発生するエラーを回避する方法を紹介します。

SuspensionManagerはアプリがSuspension状態に入るとき、アプリのページ状態の保存を手伝うクラスです。ページ状態を保存したあと、アプリの次回の起動時に終了前の状態を復元するために使います。FrameクラスのNavigateメソッドでページ移動を行うとき、パラメータなしでページクラスタイプだけを指定して移動する場合、SuspensionManagerは正常にページ状態を保存してくれます。

問題は、Navigateメソッドにページタイプ以外にパラメータを指定する場合に発生します。パラメータにintやbool,stringなどWindowsRTの基本データ型を指定するときは問題ありませんが、自作のクラスや配列(例えばobject[])など、複雑なデータ型を指定するとSuspensionManagerのSaveAsync()メソッドの途中にエラーが発生します。これを解決するためにSuspensionManagerを修正して複雑なデータ形を保存できるようにする方法もありますが、私はデフォルトのデータやクラスはなるべく修正しないで使う方を好みますので、逆に複雑なデータ形をWindowsRTの基本データ型に変換する方法を使います。

  1. パラメータとして渡すクラスを自作する。クラスは[DataContract]のAttributeをつけておきます。またクラス内の保存する変数にすべて[DataMember]Attributeをつけます。これをつけておかないとその変数はシリアライズされません。
  2. 1のクラスをXML形式のstringにシリアライズし、FrameのNavigateのパラメータとして渡します。
  3. 移動先のページからstring型で渡されたパラメータを元のクラスに復元します。

1の自作クラスの部分は省略し、2,3のXML形式のstringにシリアライズ、デシリアライズするコードを紹介します。

public static string ToXMLText(NaviParameter obj)
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(NaviParameter));

            using (MemoryStream memoryStream = new MemoryStream())
            using(StreamReader reader = new StreamReader(memoryStream))
            {
                StringWriter sw = new StringWriter();
                serializer.WriteObject(memoryStream, obj);
                memoryStream.Seek(0, SeekOrigin.Begin);
                string text = reader.ReadToEnd();
                return text;
            }
        }
public static NaviParameter FromXMLText(string xmlText)
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(NaviParameter));

            using (StringReader stringReader = new StringReader(xmlText))
            using (XmlReader xmlReader = XmlReader.Create(stringReader))
            {
                return (NaviParameter)serializer.ReadObject(xmlReader);
            }
        }

私の場合、ページ移動のパラメータがあんまり種類がなかったので直接型を指定していますが、ジェネリックパターンを利用するのもいいと思います。

 

参考にしたページ:Jsonを利用したパラメータの文字列化

 

作成者: kkc0923

KANOTYPE管理者。

1件のコメント

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Loading...